Предотвратите скрытие панели навигации UISearchDisplayController

Всякий раз, когда пользователь начинает редактировать строку поиска UISearchDisplayController , controller поиска становится активным и скрывает навигационную панель представления, представляя представление таблицы поиска. Можно ли запретить UISearchDisplayController скрывать навигационную панель, не переопределяя ее?

    Новый class UISearchController представленный с iOS 8, имеет свойство hidesNavigationBarDuringPresentation которое вы можете установить на false, если вы хотите, чтобы панель навигации была видимой (по умолчанию она по-прежнему будет скрыта).

    Я просто отлаживал бит в UISearchDisplayController и обнаружил, что он вызывает частный метод в UINavigationController, чтобы скрыть панель навигации. Это происходит в -setActive: анимированный :. Если вы подclassифицируете 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.

    Простейшее решение и отсутствие хаков.

     @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 

    Вышеуказанные ответы не помогли мне. Мое решение – обмануть UISearchDisplayController, думая, что не существует UINavigationController.

    В вашем controllerе просмотра добавьте этот метод

     - (UINavigationController *)navigationController { return nil; } 

    У меня не было никаких неприятных побочных эффектов, несмотря на кажущуюся очень плохую идею … Если вам нужно попасть на controller навигации, используйте [super navigationController] .

    Пробовал это по-другому, без подclassа UISearchDisplayController. В вашем classе UIViewController, где вы устанавливаете делегат для UISearchDisplayController, реализуйте searchDisplayControllerDidBeginSearch: и добавьте использование

     [self.navigationController setNavigationBarHidden:NO animated:YES]; 

    Сделал трюк для меня, надеюсь, что это поможет.

    Начиная с iOS 8.0 такое же поведение можно достичь, установив для свойства self.searchController.hidesNavigationBarDuringPresentation объекта UISearchController self.searchController.hidesNavigationBarDuringPresentation false.

    Код в Swift выглядит так:

     searchController.hidesNavigationBarDuringPresentation = false 

    Я столкнулся с этим, решая немного другую проблему. При использовании 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; } 

    Вам нужно будет вручную активировать controller отображения поиска, когда пользователь -searchBarShouldBeginEditing: строку поиска (в -searchBarShouldBeginEditing: и вручную -searchBarShouldBeginEditing: панель поиска, когда пользователь заканчивает поиск (в -searchDisplayControllerWillEndSearch: .

     #pragma mark  - (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 )self.searchDisplayController; return YES; } #pragma mark  - (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; } 

    Действительно приятное решение, но это сбой моего приложения под 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]; } } 

    Кажется, это решает это для меня. Проверено как в 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]; } 

    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]; } 

    Причина показа / скрытия строки состояния

    Я считаю, что лучшим решением является внедрение UISearchDisplayController самостоятельно.

    Это не так сложно. Вам нужно всего лишь реализовать UISearchBarDelegate для вашего UIViewController и включить UITableView для отображения результатов поиска.

    @ Павел прекрасно работает. Тем не менее, я пытался получить это в UIPopoverController, и текст в поле слегка подталкивается, когда текстовое поле строки поиска становится первым ответчиком, и это выглядит немного уродливо, поэтому я исправил его, вызвав метод super с animated набором к NO .

    Как отметил jrc, «отключить UISearchDisplayController от контроля любого UISearchBar», похоже, работает на меня. Если я передаю nil в качестве параметра при создании UISearchDisplayController, панель навигации остается видимой во все времена:

     searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:nil contentsController:self]; 

    Я добавлял настраиваемую навигационную панель на моем ViewController, которая скрывалась при поиске, быстро, но не очень хорошая проблема.

     - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{ [self.view addSubview:_navBar]; } 

    _navBar – это UINavigationBar, добавленный программно, это помогло мне скрыть панель навигации.

    Просто хотел добавить к ответу стиги. Когда вы отмените поиск и снова начнете поиск – таблица результатов поиска не будет реагировать на касания, поэтому вам нужно добавить следующую строку

     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]; } } 
    Давайте будем гением компьютера.