UISearchController не перерисовывает навигационную панель при повороте
Я реализовал UISearchController, и он отлично работает, кроме...
Когда я нажимаю на панель поиска, панель навигации исчезает красиво, как ожидалось. Когда я поворачиваю телефон в альбомный вид, я получаю это представление, которое имеет смысл.
![enter image description here]()
Однако, когда я поворачиваю телефон обратно в портретный вид (все еще выбранный в области типа поиска), я получаю следующее представление.
![enter image description here]()
Вы можете видеть, что панель навигации никогда не появляется. Я чувствую, что реализую базовый контроллер поиска. Что может быть причиной этого?
self.venueSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.venueSearchController.searchResultsUpdater = self;
self.venueSearchController.searchBar.delegate = self;
self.venueSearchController.dimsBackgroundDuringPresentation = NO;
self.venueSearchController.hidesNavigationBarDuringPresentation = YES;
self.venueSearchController.searchBar.frame = CGRectMake(self.venueSearchController.searchBar.frame.origin.x, self.venueSearchController.searchBar.frame.origin.y, self.venueSearchController.searchBar.frame.size.width, 44.0);
self.definesPresentationContext = YES;
self.navigationController.navigationBar.translucent = YES;
self.venueSearchController.searchBar.translucent = YES;
self.tableView.tableHeaderView = self.venueSearchController.searchBar;
Ответы
Ответ 1
Похоже, что UISearchController
забывает reset кадр searchBar
при появлении строки состояния. Я думаю, что это, вероятно, ошибка в UISearchController
; кажется, что некоторые из них перечислены в radar. Кажется, что searchBar superview (который является внутренним для UISearchController) заканчивается с неправильной высотой. Это вызывает недовольство, поскольку поэтому решение включает вхождение в иерархию представлений searchController, которые Apple может изменить... вы можете добавить проверку версии iOS, чтобы она выполнялась только для определенных версий.
Если вы добавите код ниже в свой контроллер просмотра, он будет вызываться, когда изменяется коллекция признаков. Он проверяет, что: a) активный контроллер поиска, b) статусBar не скрыт, и c) источник searchBar-y равен 0, и если это так, он увеличивает высоту надзора на высоту statusBar, которая перемещается searchBar.
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
let app = UIApplication.sharedApplication()
if searchController!.active && !app.statusBarHidden && searchController?.searchBar.frame.origin.y == 0 {
if let container = self.searchController?.searchBar.superview {
container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + app.statusBarFrame.height)
}
}
}
Цель C
- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {
[super traitCollectionDidChange: previousTraitCollection];
if(self.venueSearchController.active && ![UIApplication sharedApplication].statusBarHidden && self.venueSearchController.searchBar.frame.origin.y == 0)
{
UIView *container = self.venueSearchController.searchBar.superview;
container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height);
}
}
Ответ 2
Вам может потребоваться реализовать UIBarPositioningDelegate
в вашем контроллере вида.
self.venueSearchController.searchBar.delegate = self;
SearchBar ищет ответ от этого делегата.
@protocol UISearchBarDelegate <UIBarPositioningDelegate>
Добавьте следующее в свой self
(я предполагаю, что это ViewController)
#pragma mark - <UIBarPositioningDelegate>
// Make sure NavigationBar is properly top-aligned to Status bar
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
if (bar == self.venueSearchController.searchBar) {
return UIBarPositionTopAttached;
}
else { // Handle other cases
return UIBarPositionAny;
}
}
Ответ 3
Я считаю, что это может быть проблемой с тем, как макет UITableViewController имеет дело с навигационной панелью, а не с панелью навигации, когда она появляется в случае, когда вы вращаетесь назад.
Я думаю, вы можете решить эту проблему, заменив ваш UITableViewController на UIViewController, в который вы удаляете UITableView. Затем установите верхнее ограничение представления таблицы в качестве верхнего руководства по макету. Установите боковые ограничения влево, вправо, внизу 0.
Это должно гарантировать, что таблица всегда будет находиться ниже строки состояния и все равно будет двигаться правильно, когда навигационная панель вернется и вернется.
Смотрите это обсуждение: iOS 7: UITableView отображается в строке состояния
Ответ 4
Я столкнулся с аналогичной проблемой с UISearchController
, используя его с navigationItem
. Это выглядит по-другому, но вызвано той же самой проблемой: UISearchController
НЕ обновляет кадр searchBar
, когда появляется строка состояния.
Но вместо ручной настройки кадров иерархии представления searchBar
вы должны просто заставить его обновить макет, переключая hidesNavigationBarDuringPresentation
назад и вперед во время поворота в traitCollectionDidChange
или viewWillTransition(to size: CGSize, with cooridnator: UIViewControllerTransitionCoordinator)
:
Таким образом, исправление будет выглядеть так:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 11, *) {
navigationItem.hidesSearchBarWhenScrolling.toggle()
navigationItem.hidesSearchBarWhenScrolling.toggle()
}
}
А вот как выглядит оригинальный выпуск.
![Search in landscape without status bar]()
Затем вращается и получил это:
![Search in portrait after status bar reappearing]()
Ответ 5
Я временно "исправил" это, отключив "Скрыть строку состояния" в настройках.
![enter image description here]()