UISearchBar, представленный UISearchController в представлении заголовка таблицы, слишком сильно анимируется, когда активен

Я использую UISearchController для представления панели поиска внутри представления заголовка представления таблицы:

...
self.searchController.hidesNavigationBarDuringPresentation = NO;            
self.presentingTVC.tableView.tableHeaderView = self.searchController.searchBar;
[self.searchController.searchBar sizeToFit];
self.presentingTVC.tableView.tableHeaderView = self.searchController.searchBar;

(где требуется установка свойства tableHeaderView дважды, поскольку в противном случае представление заголовка перекрывает первую строку, см. пару ответов на SO )

Вот как это выглядит, в идеальном положении в неактивном состоянии: Неактивная панель поиска в правильном положении

Панель поиска должна оставаться на месте, когда она активна - я не хочу, чтобы она двигалась вверх, чтобы скрыть панель навигации. Но он неожиданно анимируется, оставляя пустое пространство между ним и панелью навигации:

Снимок экрана, на котором панель поиска анимирована слишком далеко вниз

Вот видео странной анимации панели поиска.

Если я просто использую панель поиска отдельно от UISearchController, она не будет вести себя так же, когда станет активной.

В моем контроллере представления представления у меня есть self.definesPresentationContext = YES; и self.navigationController.navigationBar.translucent = YES;, а в IB ни один из полей "удлинить края" не активен (все казалось возможными вещами, которые могут сбить представление поиска при чтении вокруг).

Кто-нибудь знает, как я могу остановить анимацию панели поиска?


person Zoë Smith    schedule 04.02.2015    source источник
comment
У меня такая же проблема. Я пробовал просмотреть образец проекта Apple здесь: developer.apple.com / library / ios / samplecode /, но все равно не повезло. Обновлю, если найду ответ.   -  person Brian Sachetta    schedule 06.02.2015
comment
Ни одно из решений не помогло мне: (   -  person Yestay Muratov    schedule 22.11.2016
comment
Ваша ссылка на видео теперь не работает.   -  person trapper    schedule 05.12.2016
comment
Надо исправить сейчас :)   -  person Zoë Smith    schedule 05.12.2016


Ответы (15)


Итак, я наконец нашел решение для себя. Хотя более чем вероятно, что у нас есть другие вещи в нашем коде / раскадровке (поэтому на этот вопрос сложно ответить), по большей части я следовал руководству Apple по UISearchController: (https://developer.apple.com/library/ios/samplecode/TableSearch_UISearchController/Introduction/Intro.html )

Практически весь мой код идентичен их, но я не мог заставить панель поиска не прыгать при нажатии внутри нее. Я проверил «под непрозрачными полосами» как исходное табличное представление, так и табличное представление результатов поиска в моей раскадровке. Это заставило панель поиска перестать прыгать.

Но была одна последняя проблема, которая заключалась в том, что первая строка представления таблицы результатов была скрыта панелью поиска. Чтобы исправить это, я добавил self.tableView.contentInset = UIEdgeInsetsMake(kHeightOfTableViewCells, 0, 0, 0); к viewDidLoad методу представления таблицы результатов. Вуаля!

person Brian Sachetta    schedule 06.02.2015
comment
Здесь следует отметить, что kHeightOfTableViewCells - это константа, которую я установил в своем классе табличного представления, чтобы определить высоту моих ячеек. - person Brian Sachetta; 06.02.2015
comment
Да, я думаю, это уже кое-что! - см. также stackoverflow.com/a/19585104/2199136 - person Zoë Smith; 08.02.2015
comment
Под непрозрачными полосами на контроллере представления в раскадровке все сделали за меня, спасибо! - person C0D3; 08.12.2015
comment
Недавно я сделал свою панель навигации непрозрачной, и от этого она подпрыгивала, какое безумное поведение! - person Bernardo Santana; 06.06.2016
comment
Спасибо! Это помогло. Интересно, как вы пришли к такому решению? О, как мне нравятся странные скачки или пропуски в TableView, которые можно предотвратить с помощью непонятных логических флагов ... - person Tomek Cejner; 06.06.2017
comment
Честно говоря, я просто экспериментировал со всеми возможными вариантами, и этот наконец сработал. В то время этот был чем-то вроде головной боли. - person Brian Sachetta; 07.06.2017

Старый вопрос, но я смог решить эту проблему, установив

self.extendedLayoutIncludesOpaqueBars = YES;

на мой взгляд контроллер. Я думаю, что проблема вызвана непрозрачной панелью навигации, но установкой hidesNavigationBarDuringPresentation на NO на вашем контроллере поиска, в результате чего панель поиска неправильно позиционируется при фокусировке.

person ppilone    schedule 05.11.2015
comment
public var extendedLayoutIncludesOpaqueBars: Bool // Defaults to NO, but bars are translucent by default on 7_0. Поэтому я действительно думаю, что Apple по умолчанию должна установить ДА, поскольку iOS7 - person dOM; 09.06.2016
comment
Это работает. Похоже, другие решения - это обходной путь. - person I make my mark; 20.03.2017
comment
Комбинация: self.definesPresentationContext = YES; и self.extendedLayoutIncludesOpaqueBars = YES; мне подходит. - person garanda; 26.09.2017
comment
Решение Garanda тоже работает для меня, разница в том, что я добавил эти 2 в раскадровку при чтении раскадровки в xml. ‹ViewController storyboardIdentifier = xxxVC extendedLayoutIncludesOpaqueBars = YES definePresentationContext = YES id = hgJ-Px-OtG userLabel = xxxxViewController customClass = xxxxViewController ..... - person Ning; 09.08.2019

Мне удалось предотвратить смещение UISearchBar вниз, удалив следующую строку из моего ViewController: self.definesPresentationContext = YES;

person Piotr Tomasik    schedule 08.04.2015
comment
Сказочный ответ. Идея состоит в том, чтобы сделать корневой контроллер представления представителем контроллера поиска, когда в миксе есть несколько контейнерных VC. Не устанавливая, мы возвращаемся к контроллеру корневого представления, решаем коварные проблемы, возникающие из отсоединенных контроллеров родительского представления. Спасибо! - person John Doe; 17.10.2016
comment
Сначала это сработало. Но позже я заметил, что из-за этого исправления у меня произошел сбой: если я выполняю поиск, а результатов нет, нажатие кнопки в заполнителе не вызывает сбоя селектора - переход кнопки не работает. Возможно особенности моей настройки, но будьте осторожны. Комбинация self.definesPresentationContext = true и self.extendedLayoutIncludesOpaqueBars = true сработала лучше для моей установки. - person Vitalii; 19.12.2017

definePresentationContext = true

override func viewDidLoad() {
        super.viewDidLoad()

        searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false

        searchController.dimsBackgroundDuringPresentation = true
        searchController.searchBar.searchBarStyle = UISearchBarStyle.Prominent
        self.tableView.tableHeaderView = searchController.searchBar

        definesPresentationContext = true
person Gleb    schedule 10.12.2015
comment
Мне тоооооо! definesPresentationContext = true - это жизнь! - person Grifas; 15.05.2017
comment
Сработало у меня! В другом сегменте контроллер работал нормально, но в другом стеке он исчезал. Это устранило проблему на обоих. - person Pomo-J; 27.10.2018

Моя очередь. У меня также была эта проблема, когда я следил за примером кода WWDC.

Я заметил, что если бы я не установил свойство scopeButtonTitles для searchBar, searchBar не был бы виден. При ближайшем рассмотрении у него была просто рамка CGRectZero. Это означает, что установка scopeButtonTitles устанавливает скрытый фрейм. Поэтому, если вы не хотите отображать какой-либо объект scopeButtonTitles, но при этом не хотите жестко указывать UISearchBar на определенную высоту, установите для scopeButtonTitles пустой массив.

self.searchController = UISearchController(searchResultsController: nil)
self.searchController.searchResultsUpdater = self
self.searchController.searchBar.scopeButtonTitles = []
self.tableView.tableHeaderView = self.searchController.searchBar

Установка для scopeButtonTitles массива из 1 строк не будет отображать заголовки кнопок области, но по-прежнему будет иметь логику для работы с представлением, что по существу испортит макет.

Реквизит команде QA Apple (применимо к iOS 8)

person Sozin's Comet    schedule 28.04.2015
comment
Просто восхитительно. Работает для моего представления таблицы с настраиваемым макетом строк на iOS 8! - person Kedar Paranjape; 08.05.2015
comment
Установка пустого массива для области определенно решает эту проблему в iOS8, когда вы используете настраиваемый контроллер представления и собственное представление таблицы / коллекции. - person Andrew; 12.06.2015
comment
Вы также можете позвонить sizeToFit, чтобы исправить проблему нулевого размера. - person Craig McMahon; 06.08.2015

Я столкнулся с этой проблемой совсем недавно, и ни одно из решений не помогло мне. Возможно, потому, что мой пользовательский интерфейс более сложен (мое табличное представление с поддержкой поиска содержится в UITabController внутри UiNavigationController) в любом случае, ни один из вышеперечисленных рабочих. Я мог бы просто решить свою проблему с помощью этого очень аккуратного фрагмента кода, который я нашел по адресу: UISearchController Панель навигации не отображается повторно при повороте

- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
    if (bar == searchController.searchBar) {
        return UIBarPositionTopAttached;
    }
    else { // Handle other cases
        return UIBarPositionAny;
    }
}

Еще кое-что, что нужно добавить: после того, как вся иерархия моего контроллера расширяется под непрозрачными и верхними панелями, моя панель поиска начала отображаться скрытой под панелью навигации и могла появиться сразу после того, как могло произойти вращение. это было для меня сигналом, что есть некоторая ошибка в макете, и некоторая информация о моем макете была неправильной. этот метод делегата помогает моему контроллеру понять ситуацию с панелью поиска, в противном случае кочевой!

person M. Porooshani    schedule 03.05.2015

Нашел! Кажется, это оскорбительная фраза в viewDidLoad представляющего vc:

self.edgesForExtendedLayout = UIRectEdgeNone;

Удалил это, и панель поиска осталась на месте, как и предполагалось.

person Zoë Smith    schedule 05.02.2015
comment
Это не помогло мне, поскольку у меня нет этого кода в моем проекте. Я попытался использовать другой пример проекта: github.com/dempseyatgithub/Sample-UISearchController и разбить его на части. по частям, но все равно не повезло. Продолжу поиски. - person Brian Sachetta; 06.02.2015
comment
Хм раздражает! Вы можете установить edgeForExtendedLayout на контроллере представления в раскадровке, а также с помощью флажков Extend Edges. Может быть, перепроверьте их? - person Zoë Smith; 06.02.2015
comment
Кроме того, я сталкиваюсь со странными анимациями из-за того, что UISearchController теперь представляет собой полноценный представленный VC - так, например, я видел странную анимацию увольнения, когда панель поиска опускалась в нижнюю часть VC при нажатии кнопки Cancel. Это произошло из-за того, что представляющий виртуальный канал предоставил контекст перехода с выбранным типом вертикального перехода. Все для того, чтобы сказать, что, возможно, если бы я немного лучше понимал, как работают механизмы представления, я мог бы легче отлаживать все эти странности ...! - person Zoë Smith; 06.02.2015
comment
Спасибо за дополнительную информацию. Я возился с флажками контроллера представления на раскадровке. Я исправил прыжок при прокрутке, установив флажок «Под непрозрачными полосами», но теперь первая строка таблицы в контроллере поиска скрыта полосой поиска. Приближаться .... - person Brian Sachetta; 06.02.2015

снятие флажка Настроить вставки прокрутки.

а также

проверка Под верхними полосами

Исправлена ​​ моя проблема  введите описание изображения здесь

person Basil Mariano    schedule 27.02.2017
comment
Спасибо чувак! после долгих поисков это единственное решение, которое сработало для меня. ваше здоровье!! ты спас мне день - person Aatish Rajkarnikar; 09.06.2017

для iOS 11 и swift 4 установите строку ниже в viewController, чтобы решить мою проблему (searchBar прыгает вниз):

self.edgesForExtendedLayout = .bottom
person side    schedule 03.11.2017

Я думаю, вы установили UISearchBar frame.original.y = 64

есть код

if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
    [self setEdgesForExtendedLayout:UIRectEdgeNone];
}

searchBar.frame = CGRectMake(0, 0, 376, 44);

стирка может вам помочь

person Hawe    schedule 06.05.2016

В моем случае установка панели навигации на self.navigationController.navigationBar.translucent = NO; устранила проблему. Кажется, что слой представления панели поиска не учитывает полупрозрачность панели навигации при размещении панели поиска.

Я понимаю, что это не идеальное решение, потому что полупрозрачность навигационной панели может отбросить макет в другом месте, но это, по крайней мере, решает проблему в случае, когда возможна непрозрачная навигационная панель.

person Alex Medearis    schedule 23.07.2015

Как упоминалось в первом посте, каждому требовалось другое решение. Итак, вот мой. Мне пришлось совместить две вещи, упомянутые на этой странице, а именно:

Swift 2:

    navigationController?.navigationBar.translucent = true

    edgesForExtendedLayout = .None
person hashier    schedule 07.06.2016

это очень просто, просто добавьте clipsToBounds = true из заголовка представления таблицы в панели поиска ведьмы.

countryTableView.tableHeaderView?.clipsToBounds = true
person Prit_Singh    schedule 12.05.2017

Если вы используете UINavigationController и TabBar, вы не можете использовать:

self.extendedLayoutIncludesOpaqueBars = true

Вам понадобится это решение: https://stackoverflow.com/a/46151063/3369381

person demylia    schedule 11.09.2017

У меня был порядок элементов в .xib файле главного контроллера.

Это сработало.

Это сработало

Это не сработало.

введите здесь описание изображения

person Pedro Góes    schedule 20.01.2020