Всякий раз, когда пользователь начинает редактирование строки поиска UISearchDisplayController
, контроллер поиска становится активным и скрывает панель навигации вида, представляя представление таблицы поиска. Можно ли предотвратить UISearchDisplayController
скрытие навигационной панели, не переопределяя ее?
Предотвратите скрытие панели навигации UISearchDisplayController
Ответ 1
Новый класс UISearchController
, представленный с iOS 8, имеет свойство hidesNavigationBarDuringPresentation
, которое вы можете установить на false, если вы хотите, чтобы панель навигации была видимой (по умолчанию она все равно будет скрыта).
Ответ 2
Я просто отлаживал бит в UISearchDisplayController и обнаружил, что он вызывает частный метод в UINavigationController, чтобы скрыть панель навигации. Это происходит в -setActive: анимированный:. Если вы подклассифицируете UISearchDisplayController и перезапишите этот метод с помощью следующего кода, вы можете не скрывать, что navigationBar скрывается, притворяясь, что он уже скрыт.
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
Сообщите мне, если это сработает для вас. Я также надеюсь, что это не сломается в будущих версиях iOS... Протестировано только на iOS 4.0.
Ответ 3
Простейшее решение и отсутствие хаков.
@interface MySearchDisplayController : UISearchDisplayController
@end
@implementation MySearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[super setActive: visible animated: animated];
[self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];
}
@end
Ответ 4
Вышеуказанные ответы не помогли мне. Мое решение состоит в том, чтобы обмануть UISearchDisplayController, полагая, что не было UINavigationController.
В вашем контроллере просмотра добавьте этот метод
- (UINavigationController *)navigationController {
return nil;
}
У меня не было никаких неблагоприятных побочных эффектов для меня, несмотря на кажущуюся очень плохую идею... Если вам нужно попасть на контроллер навигации, используйте [super navigationController]
.
Ответ 5
Пробовал это по-другому, без подкласса UISearchDisplayController. В вашем классе UIViewController, где вы устанавливаете делегат для UISearchDisplayController, реализуйте searchDisplayControllerDidBeginSearch: и добавьте использование
[self.navigationController setNavigationBarHidden:NO animated:YES];
Сделал трюк для меня, надеюсь, что это поможет.
Ответ 6
Так как iOS 8.0 такое же поведение может быть достигнуто установкой свойства UISearchController
self.searchController.hidesNavigationBarDuringPresentation
на значение false.
Код в Swift выглядит следующим образом:
searchController.hidesNavigationBarDuringPresentation = false
Ответ 7
Я столкнулся с этим, решая немного другую проблему. При использовании UISearchDisplayController я хочу, чтобы строка поиска находилась в панели навигации (не под).
Не трудно разместить панель поиска на панели навигации (см. UISearchBar и UINavigationItem). Однако UISearchDisplayController предполагает, что панель поиска всегда находится под панелью навигации и (как обсуждалось здесь) настаивает на скрытии панели навигации при входе в поиск, поэтому все выглядит ужасно. Кроме того, UISearchDisplayController отображает строку поиска, более легкую, чем обычно.
Я нашел решение. Фокус в том, чтобы (контр-интуитивно) отменить UISearchDisplayController от управления любым UISearchBar вообще. Если вы используете xibs, это означает удаление экземпляра строки поиска или, по крайней мере, отсоединение выхода. Затем создайте свой собственный UISearchBar:
- (void)viewDidLoad
{
[super viewDidLoad];
UISearchBar *searchBar = [[[UISearchBar alloc] init] autorelease];
[searchBar sizeToFit]; // standard size
searchBar.delegate = self;
// Add search bar to navigation bar
self.navigationItem.titleView = searchBar;
}
Вам нужно будет вручную активировать контроллер отображения поиска, когда пользователь удаляет строку поиска (в -searchBarShouldBeginEditing:
) и вручную отбрасывает панель поиска, когда пользователь заканчивает поиск (в -searchDisplayControllerWillEndSearch:
).
#pragma mark <UISearchBarDelegate>
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Manually activate search mode
// Use animated=NO so we'll be able to immediately un-hide it again
[self.searchDisplayController setActive:YES animated:NO];
// Hand over control to UISearchDisplayController during the search
searchBar.delegate = (id <UISearchBarDelegate>)self.searchDisplayController;
return YES;
}
#pragma mark <UISearchDisplayDelegate>
- (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController
*)controller {
// Un-hide the navigation bar that UISearchDisplayController hid
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
- (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController
*)controller {
UISearchBar *searchBar = (UISearchBar *)self.navigationItem.titleView;
// Manually resign search mode
[searchBar resignFirstResponder];
// Take back control of the search bar
searchBar.delegate = self;
}
Ответ 8
Действительно приятное решение, но это сбой моего приложения под iOS6. Я должен был внести следующие изменения, чтобы заставить его работать.
@implementation ICSearchDisplayController
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if (visible == YES) {
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
} else {
[super setActive:NO animated:NO];
}
}
Ответ 9
Кажется, это решает это для меня. Проверено как в iOS5/6.1. Никаких визуальных проблем, которые я мог видеть.
- (void)viewDidAppear
{
[super viewDidAppear];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillAppear:(NSNotification *)notification
{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
-(void)viewDidLayoutSubviews{
[self.navigationController setNavigationBarHidden:NO animated:NO];
}
Ответ 10
iOS 7 немного шутит... для меня это отлично работает:
/**
* Overwrite the `setActive:animated:` method to make sure the UINavigationBar
* does not get hidden and the SearchBar does not add space for the statusbar height.
*
* @param visible `YES` to display the search interface if it is not already displayed; NO to hide the search interface if it is currently displayed.
* @param animated `YES` to use animation for a change in visible state, otherwise NO.
*/
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
Причина показа/скрытия строки состояния
Ответ 11
Я думаю, лучшее решение - это реализовать UISearchDisplayController самостоятельно.
Это не так сложно. Вам нужно всего лишь реализовать UISearchBarDelegate для вашего UIViewController и включить UITableView для отображения результатов поиска.
Ответ 12
@Pavel работает отлично. Тем не менее, я пытался получить это в UIPopoverController, и текст в поле слегка подталкивается, когда текстовое поле строки поиска становится первым ответчиком, и это выглядит немного уродливо, поэтому я исправил его, вызвав метод super
с помощью
animated
установлен на NO
.
Ответ 13
Как отметил jrc, "отключить UISearchDisplayController от контроля любого UISearchBar", похоже, работает на меня. Если я передаю nil в качестве параметра при создании UISearchDisplayController, панель навигации остается видимой во все времена:
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:nil contentsController:self];
Ответ 14
Я добавлял настраиваемую панель навигации на моем ViewController, которая скрывалась при поиске, быстро, но не очень хорошая проблема:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
[self.view addSubview:_navBar];
}
_navBar - это UINavigationBar, добавленный программно, это помогло мне скрыть панель навигации.
Ответ 15
Просто хотел добавить к stigi ответ. Когда вы отмените поиск и снова начнете поиск - таблица результатов поиска не будет реагировать на касания, поэтому вам нужно добавить следующую строку
self.searchResultsTableView.alpha = 1;
Таким образом обновленный код выглядит следующим образом
- (void)setActive:(BOOL)visible animated:(BOOL)animated;
{
if(self.active == visible) return;
if (visible) {
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
self.searchResultsTableView.alpha = 1;
[self.searchBar becomeFirstResponder];
} else {
[super setActive:visible animated:animated];
[self.searchBar resignFirstResponder];
}
}