Evite que UISearchDisplayController oculte la barra de navegación

Cada vez que un usuario comienza a editar la barra de búsqueda de UISearchDisplayController , el controlador de búsqueda se activa y oculta la barra de navegación de la vista al presentar la vista de la tabla de búsqueda. ¿Es posible evitar que UISearchDisplayController la barra de navegación sin UISearchDisplayController a UISearchDisplayController ?

    La nueva clase UISearchController presentada con iOS 8 tiene una propiedad hidesNavigationBarDuringPresentation que puedes establecer en falso si deseas mantener la barra de navegación visible (de manera predeterminada, seguirá oculta).

    Acabo de depurar un poco en UISearchDisplayController y descubrí que está llamando a un método privado en UINavigationController para ocultar la barra de navegación. Esto sucede en -setActive: animated :. Si subclase UISearchDisplayController y sobrescribe este método con el siguiente código, puede evitar que se oculte la barra de navegación si se simula que ya está oculta.

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

    Hazme saber si esto funciona para ti. También espero que esto no se rompa en futuras versiones de iOS … Probado solo en iOS 4.0.

    La solución más simple y sin hacks.

     @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 

    Las respuestas anteriores no funcionaron del todo bien para mí. Mi solución es engañar al UISearchDisplayController para que crea que no haya un UINavigationController.

    En su controlador de vista, agregue este método

     - (UINavigationController *)navigationController { return nil; } 

    Esto no tuvo efectos secundarios desfavorables para mí, a pesar de parecer una idea realmente mala … Si necesitas acceder al controlador de navegación, utiliza [super navigationController] .

    Intenté esto de una manera diferente, sin subclasificar UISearchDisplayController. En tu clase UIViewController donde configuras el delegado para UISearchDisplayController, implementa searchDisplayControllerDidBeginSearch: y agrega el uso

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

    Hice el truco para mí, espero que eso ayude.

    Desde iOS 8.0, se puede lograr el mismo comportamiento estableciendo la propiedad self.searchController.hidesNavigationBarDuringPresentation en false.

    El código en Swift se ve así:

     searchController.hidesNavigationBarDuringPresentation = false 

    Me encontré con esto mientras abordaba un problema ligeramente diferente. Mientras uso UISearchDisplayController, quiero que la barra de búsqueda esté en la barra de navegación (no debajo).

    No es difícil colocar la barra de búsqueda en la barra de navegación (ver UISearchBar y UINavigationItem ). Sin embargo, UISearchDisplayController supone que la barra de búsqueda siempre se encuentra debajo de la barra de navegación y (como se explica aquí) insiste en ocultar la barra de navegación al ingresar la búsqueda, por lo que las cosas se ven terribles. Además, UISearchDisplayController da color a la barra de búsqueda más claro de lo normal.

    Encontré una solución. El truco es (de manera intuitiva) desenganchar UISearchDisplayController del control de cualquier UISearchBar en absoluto. Si usa xibs, esto significa eliminar la instancia de la barra de búsqueda, o al menos desenganchar la toma de stream. Luego crea tu propia 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; } 

    Tendrá que activar manualmente el controlador de visualización de búsqueda cuando el usuario toque la barra de búsqueda (en -searchBarShouldBeginEditing: y descarte manualmente la barra de búsqueda cuando el usuario finalice la búsqueda (en -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; } 

    Una solución realmente agradable, pero estaba bloqueando mi aplicación en iOS6. Tuve que hacer la siguiente modificación para que funcione.

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

    Esto parece resolverlo por mí. Probado en iOS5 / 6.1. No hay problemas visuales que pueda ver.

     - (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 arruina las cosas un poco … para mí esto funcionó perfectamente:

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

    La razón para mostrar / ocultar la barra de estado

    Creo que la mejor solución es implementar UISearchDisplayController usted mismo.

    No es tan difícil. Solo necesita implementar UISearchBarDelegate para su UIViewController e incluir una UITableView para mostrar sus resultados de búsqueda.

    @ Pavel’s funciona perfectamente bien. Sin embargo, estaba tratando de poner esto en un UIPopoverController y el texto en el campo se empuja ligeramente cuando el campo de texto de la barra de búsqueda se convierte en el primer respondedor, y se ve un poco feo, así que lo arreglé llamando al super con el conjunto animated a NO .

    Como jrc señaló “desenganchar UISearchDisplayController del control de cualquier UISearchBar” parece funcionar para mí. Si paso nil como parámetro al crear UISearchDisplayController, la barra de navegación permanece visible en todo momento:

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

    Estaba agregando una barra de navegación personalizada en mi ViewController que se estaba ocultando en la búsqueda, una solución rápida pero no tan buena era

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

    _navBar es UINavigationBar agregado programáticamente, esto me ayudó a evitar que la barra de navegación se escondiera.

    Solo quería agregar a la respuesta de Stigi. Cuando cancela la búsqueda y comienza la búsqueda nuevamente, la tabla de resultados de búsqueda no reactjsrá a los toques, por lo que debe agregar la siguiente línea

     self.searchResultsTableView.alpha = 1; 

    Así que el código actualizado se ve de la siguiente manera

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