Empêcher un UISearchDisplayController de masquer la barre de navigation

UISearchDisplayController utilisateur commence à modifier la barre de recherche d’un UISearchDisplayController , le contrôleur de recherche devient actif et masque la barre de navigation de la vue lors de la présentation de la vue de la table de recherche. Est-il possible d’empêcher un UISearchDisplayController de cacher la barre de navigation sans la réimplémenter?

    La nouvelle classe UISearchController introduite avec iOS 8 possède une propriété hidesNavigationBarDuringPresentation que vous pouvez définir sur false si vous souhaitez que la barre de navigation rest visible (par défaut, elle sera toujours masquée).

    J’ai juste débogué un peu dans UISearchDisplayController et j’ai trouvé qu’il appelait une méthode privée sur UINavigationController pour masquer la barre de navigation. Cela se passe dans -setActive: animé :. Si vous sous-classe UISearchDisplayController et remplacez cette méthode par le code suivant, vous pouvez empêcher que la barre de navigation ne soit masquée en simulant qu’elle soit déjà masquée.

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

    Faites-moi savoir si cela fonctionne pour vous. J’espère aussi que cela ne sera pas cassé dans les futures versions iOS … Testé sur iOS 4.0 uniquement.

    La solution la plus simple et pas de piratage.

     @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 

    Les réponses ci-dessus ne fonctionnaient pas très bien pour moi. Ma solution est de tromper le UISearchDisplayController en lui faisant croire qu’il n’y avait pas de UINavigationController.

    Dans votre contrôleur de vue, ajoutez cette méthode

     - (UINavigationController *)navigationController { return nil; } 

    Cela n’a eu aucun effet secondaire indésirable pour moi, même si cela semblait être une très mauvaise idée … Si vous devez accéder au contrôleur de navigation, utilisez [super navigationController] .

    Essayé cela d’une manière différente, sans sous-classer UISearchDisplayController. Dans votre classe UIViewController où vous définissez le délégué pour UISearchDisplayController, implémentez searchDisplayControllerDidBeginSearch: et ajoutez

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

    J’ai fait le tour pour moi, j’espère que ça aide.

    Depuis iOS 8.0, le même comportement peut être obtenu en définissant la propriété self.searchController.hidesNavigationBarDuringPresentation sur false.

    Le code dans Swift ressemble à ceci:

     searchController.hidesNavigationBarDuringPresentation = false 

    Je me suis heurté à un problème légèrement différent. Lors de l’utilisation d’UISearchDisplayController, je souhaite que la barre de recherche se trouve dans la barre de navigation (pas sous).

    Il n’est pas difficile de placer la barre de recherche dans la barre de navigation (voir UISearchBar et UINavigationItem ). Cependant, UISearchDisplayController suppose que la barre de recherche se trouve toujours sous la barre de navigation et (comme indiqué ici) insiste pour masquer la barre de navigation lors de la saisie de la recherche. De plus, UISearchDisplayController rend la barre de recherche plus claire que la normale.

    J’ai trouvé une solution. L’astuce consiste à (contre-intuitivement) décrocher UISearchDisplayController de tout contrôle de UISearchBar. Si vous utilisez des xibs, cela signifie que vous devez supprimer l’instance de la barre de recherche ou, du moins, décrocher la prise. Ensuite, créez votre propre 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; } 

    Vous devez activer manuellement le contrôleur d’affichage de recherche lorsque l’utilisateur appuie sur la barre de recherche (dans -searchBarShouldBeginEditing: et -searchBarShouldBeginEditing: manuellement la barre de recherche lorsque l’utilisateur termine la recherche (dans -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; } 

    Vraiment une bonne solution, mais il y avait un crash de mon application sous iOS6. J’ai dû apporter les modifications suivantes pour que cela fonctionne.

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

    Cela semble le résoudre pour moi. Testé dans iOS5 / 6.1. Aucun problème visuel que j’ai pu voir.

     - (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 bousille un peu la situation… pour moi, cela a parfaitement fonctionné:

     /** * 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 raison de montrer / masquer la barre d’état

    Je pense que la meilleure solution consiste à implémenter le UISearchDisplayController vous-même.

    Ce n’est pas si difficile. Vous devez seulement implémenter UISearchBarDelegate pour votre UIViewController et inclure un UITableView pour afficher vos résultats de recherche.

    @ Pavel’s fonctionne parfaitement. Cependant, j’essayais de mettre cela dans un UIPopoverController et le texte dans le champ est poussé légèrement lorsque le champ de texte de la barre de recherche devient le premier répondeur, et cela semble un peu moche, donc j’ai corrigé en appelant la méthode super avec un jeu animated à NO .

    Comme jrc l’a fait remarquer, «décrocher UISearchDisplayController du contrôle de toute UISearchBar» semble fonctionner pour moi. Si je passe nil en paramètre lors de la création de UISearchDisplayController, la barre de navigation rest visible à tout moment:

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

    J’ajoutais une barre de navigation personnalisée sur mon ViewController qui se cachait à la recherche, un correctif rapide mais pas si

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

    _navBar est UINavigationBar ajouté par programmation, ce qui m’a aidé à masquer la barre de navigation.

    Je voulais juste append à la réponse aux stigmates. Lorsque vous annulez une recherche et recommencez la recherche – le tableau des résultats de recherche ne réagira pas aux touches, vous devez donc append la ligne suivante

     self.searchResultsTableView.alpha = 1; 

    Donc, le code mis à jour ressemble à la prochaine

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