Запретить UISearchDisplayController скрывать панель навигации
всякий раз, когда пользователь начинает редактировать UISearchDisplayController
панель поиска, контроллер поиска становится активным и скрывает панель навигации представления при представлении представления таблицы поиска. Можно ли предотвратить UISearchDisplayController
от скрытия панели навигации без ее переопределения?
15 ответов:
новая
UISearchController
класс, введенный с iOS 8, имеет свойствоhidesNavigationBarDuringPresentation
который вы можете установить в false, если вы хотите, чтобы панель навигации была видна (по умолчанию она по-прежнему будет скрыта).
Я просто отладил немного в UISearchDisplayController и обнаружил, что он вызывает частный метод на UINavigationController, чтобы скрыть панель навигации. Это происходит в setActive: animated:. Если вы подкласс UISearchDisplayController и перезаписать этот метод с помощью следующего кода можно предотвратить навигационную панель от скрытия, подделав его уже скрыты.
- (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.
в контроллере вида добавьте этот метод
- (UINavigationController *)navigationController { return nil; }
У этого не было никаких неблагоприятных побочных эффектов для меня, несмотря на то, что это казалось действительно плохой идеей... Если вам нужно добраться до навигационного контроллера, используйте
[super navigationController]
.
попробовал это по-другому, без подклассов UISearchDisplayController. В вашем классе UIViewController, где вы устанавливаете делегат для UISearchDisplayController, реализуйте searchDisplayControllerDidBeginSearch: и добавьте use
[self.navigationController setNavigationBarHidden:NO animated:YES];
сделал трюк для меня, надеюсь, что помогает.
Так как iOS 8.0 такое же поведение может быть достигнуто путем установки
UISearchController
' sself.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; }
вам нужно будет вручную активировать контроллер отображения поиска, когда пользователь нажмите на строку поиска (в
-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; }
действительно хорошее решение, но это был сбой моего приложения под 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]; } }