89 votes

UISearchBar augmente la hauteur de la barre de navigation dans iOS 11

J'ai mon UISearchBar faisant partie de la barre de navigation comme :

 let searchBar = UISearchBar()
 //some more configuration to the search bar
 .....
 navigationItem.titleView = searchBar

Après la mise à jour vers iOS 11 Quelque chose de bizarre est arrivé à la barre de recherche de mon application. Sur iOS 10 et avant j'avais ma barre de navigation qui ressemblait à ça :

enter image description here

Maintenant avec iOS 11 Je l'ai fait :

enter image description here

Comme vous pouvez le constater, il y a une différence dans l'arrondi des deux barres de recherche, ce qui ne me dérange pas. Le problème est que la barre de recherche augmente la hauteur de la barre de navigation. Ainsi, lorsque je passe à un autre contrôleur, cela semble également bizarre :

enter image description here

En fait, la hauteur de la ligne noire bizarre plus la hauteur de la barre de navigation actuelle est égale à la hauteur de la barre de navigation montrée dans la deuxième image ...

Une idée pour se débarrasser de la ligne noire et avoir une hauteur de barre de navigation cohérente dans tous les contrôleurs de vue ?

0 votes

69voto

Andrew Points 1437

J'ai obtenu une ligne noire sous la barre de navigation avec la barre de recherche dans iOS 11 dans deux cas :

  • Lorsque je pousse un autre ViewController à partir du ViewController avec UISearchBar enter image description here

  • lorsque j'ai rejeté le ViewController avec UISearchBar avec "glisser vers la droite pour rejeter". enter image description here

Ma solution a été d'ajouter ce code à mon ViewController avec UISearchBar :

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.navigationController.view setNeedsLayout]; // force update layout
    [self.navigationController.view layoutIfNeeded]; // to fix height of the navigation bar
}

Mise à jour de Swift 4

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    navigationController?.view.setNeedsLayout() // force update layout
    navigationController?.view.layoutIfNeeded() // to fix height of the navigation bar
}

2 votes

A utiliser avec précaution car pour moi, l'application s'est figée lorsque j'ai essayé de revenir au contrôleur de vue précédent.

2 votes

Cette solution m'a vraiment soulagé, merci @andrew.

67voto

zgjie Points 111

Vous pouvez ajouter une contrainte de hauteur 44 à la barre de recherche pour iOS 11.

// Swift

if #available(iOS 11.0, *) {
    searchBar.heightAnchor.constraint(equalToConstant: 44).isActive = true
}

// Objective-C

if (@available(iOS 11.0, *)) {
    [searchBar.heightAnchor constraintEqualToConstant:44].active = YES;
}

0 votes

Correct. C'est comme ça que j'ai réussi à le résoudre en fait. En plus d'appeler searchBar.sizeToFit() dans le viewWillAppear Si vous ajoutez l'appel à sizeToFit() J'accepte votre réponse :) .

1 votes

@radioaktiv Je n'ai pas écrit sizeToFit() et ça marche pour moi.

0 votes

Mais qu'est-ce qui a changé exactement pour causer ce problème ?

42voto

Mai Mai Points 449

Je pense que dans iOS 11, la hauteur de UISearchBar est désormais égale à 56, et que UINavigationBar utilise l'autolayout pour s'adapter à ses sous-vues, ce qui augmente la hauteur. Si vous voulez toujours avoir UISearchBar comme titleView comme dans les versions antérieures à iOS 11, j'ai découvert que la meilleure façon de le faire est d'intégrer UISearchBar dans une vue personnalisée, et de définir la hauteur de cette vue à 44, et de l'assigner à navigationItem.titleView.

class SearchBarContainerView: UIView {  

    let searchBar: UISearchBar  

    init(customSearchBar: UISearchBar) {  
        searchBar = customSearchBar  
        super.init(frame: CGRect.zero)  

        addSubview(searchBar)  
    }

    override convenience init(frame: CGRect) {  
        self.init(customSearchBar: UISearchBar())  
        self.frame = frame  
    }  

    required init?(coder aDecoder: NSCoder) {  
        fatalError("init(coder:) has not been implemented")  
    }  

    override func layoutSubviews() {  
        super.layoutSubviews()  
        searchBar.frame = bounds  
    }  
}  

class MyViewController: UIViewController {  

    func setupNavigationBar() {  
        let searchBar = UISearchBar()  
        let searchBarContainer = SearchBarContainerView(customSearchBar: searchBar)  
        searchBarContainer.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 44)  
        navigationItem.titleView = searchBarContainer  
    }  
}

0 votes

Cela fonctionne correctement mais il y a un problème lorsque l'on passe du format portrait au format paysage.

0 votes

Excellente solution si vous n'utilisez pas la mise en page automatique. Jusqu'à présent, cela semble fonctionner pour le mode paysage également, dans le simulateur.

0 votes

J'ai posté une solution qui corrige les problèmes de changement d'orientation.

21voto

Silverwind Points 141

Essayez ce code sur le contrôleur de vue "ACKNOWLEDGEMENTS". dans viewDidLoad

self.extendedLayoutIncludesOpaqueBars = true

0 votes

Merci ! C'est la solution que j'ai finalement retenue, puisque je n'utilise pas de barres translucides.

0 votes

En effet, cela devrait être la réponse. Mais je voudrais ajouter que ce morceau de code doit être placé à la fois dans le contrôleur qui se trouve au-dessus et au-dessous du contrôleur de la barre de recherche.

1 votes

Cela a fonctionné pour moi, mais j'ai dû ajouter navigationController ?.view.layoutSubviews() dans viewWillDisappear.

4voto

Hassy Points 1943

En Objective-C

if (@available(iOS 11.0, *)) {
        [self.searchBar.heightAnchor constraintLessThanOrEqualToConstant: 44].active = YES;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X