web-dev-qa-db-fra.com

La barre de navigation personnalisée iOS 11 passe sous la barre d'état

vient de télécharger xcode 9 et j'ai ce problème étrange, sur ios 11 ma barre de navigation personnalisée semble être de moitié et est sous la barre d'état, sur ios 10 fonctionne très bien.

voici donc mon code

let newNavbar: UINavigationBar = UINavigationBar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 64))
let navItem = UINavigationItem()

//create and assign the items

newNavbar.setItems([navItem], animated: false)
view.addSubview(newNavbar)

voici une capture d'écran, ios11 à gauche et ios10 à droite,

enter image description here

13
iknowNothing

Votre code était toujours faux. Vous ne devez pas définir vous-même la hauteur d'une barre de navigation ajoutée manuellement ni la placer en haut de la vue. Vous devez épingler le haut de la barre de navigation au bas de la barre d'état (par exemple, le haut de la zone de sécurité) et lui donner un délégué afin que vous puissiez utiliser le mécanisme UIBarPositioningDelegate pour définir sa position sur .topAttached, ce qui le fera s'étirer correctement vers le haut de l'écran.

(Mais vous devriez également vous demander pourquoi vous ajoutez une barre de navigation manuellement. Il n'y a généralement aucune raison de ne pas encapsuler votre contrôleur de vue dans un UINavigationController - même si vous n'avez pas l'intention de faire de véritable navigation - juste pour obtenir la barre de navigation, avec toute sa gestion automatique.)

23
matt

Voir la barre de navigation personnalisée d'ios 11 passe sous la barre d'état / la barre d'état de chevauchement de la barre de navigation d'ios 11 pour une réponse

Je ne sais pas si c'est le même problème, mais nous l'avons rencontré également lors de la mise à niveau vers iOS 11.

Voir la barre de navigation personnalisée ios 11 passe sous la barre d'état

Nous avons réglé manuellement la hauteur de la barre de navigation à 64 et avons fixé les bords de la vue d'ensemble. Se conformer au protocole UINavigationBarDelegate et implémenter la méthode déléguée UIBarPositioningDelegate l'a résolu pour nous.

Ont été placées

navigationBar.autoPinEdgesToSuperviewEdgesExcludingEdge(.bottom)
navigationBar.autoSetDimension(.height, toSize: 64)

avec

...
  if #available(iOS 11.0, *) {
    navigationBar.topAnchor.constraint(
      equalTo: self.view.safeAreaLayoutGuide.topAnchor
    ).isActive = true
  } else {
    navigationBar.topAnchor.constraint(
      equalTo: topLayoutGuide.bottomAnchor
    ).isActive = true
  }
  navigationBar.autoPinEdge(toSuperviewEdge: .left)
  navigationBar.autoPinEdge(toSuperviewEdge: .right)
  navigationBar.delegate = self
...

public func position(for bar: UIBarPositioning) -> UIBarPosition
  return .topAttached
}

Ceci utilise le DSL purelayout pour certains des appels de mise en page automatique ( https://github.com/PureLayout/PureLayout )

Le crédit revient à https://stackoverflow.com/users/341994/matt pour une réponse

5
Darren Cheng

Essayez d'ajouter des contraintes de disposition automatique après avoir ajouté la barre de navigation à la vue

if #available(iOS 11.0, *) {
    newNavbar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    newNavbar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    newNavbar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    newNavbar.heightAnchor.constraint(equalToConstant: 64).isActive = true
}

Vous pouvez réellement utiliser toutes les contraintes, sauf la troisième, dans les versions antérieures d'iOS, mais si tout fonctionne dans les versions antérieures, vous ne voudrez peut-être pas jouer avec.

L'utilisation de la zone de mise en page sûre doit garder votre barre de navigation sous la barre d'état.

3
theMikeSwan

Tout d'abord, assurez-vous que la "barre de navigation" de votre contrôleur de navigation n'est pas cochée dans le storyboard.

Ensuite, faites glisser et déposez la barre de navigation à partir de la "bibliothèque d'objets". Donnez la contrainte Top égale à 20.

Cela fonctionnera également parfaitement dans le "simulateur iPhone X".

Codage heureux!

1
MyApp

J'ai essayé cette solution en Swift 4.1

let menuBar: UIView = {
let mb = UIView()
mb.backgroundColor = .red
mb.translatesAutoresizingMaskIntoConstraints = false
return mb
}()



private func setupMenuBar(){

view.addSubview(menuBar)

let constraints = [ menuBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                    menuBar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                    menuBar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                    menuBar.heightAnchor.constraint(equalToConstant: 50)]
NSLayoutConstraint.activate(constraints)
}
1
MJ Montes