NavigationBar consente di ritardare l’aggiornamento di barTintColor iOS10

Contesto:

Diciamo che abbiamo un NavigationController e 2 viewControllers. ViewControllerA ha una ViewControllerA navigazione blu, mentre ViewControllerB ha uno verde.

Li ho impostati in questo modo:

 override func viewWillAppear(_ animated: Bool) { self.navigationController?.navigationBar.barTintColor = UIColor.blue // Green if ViewController B } 

Funziona bene quando arrivo da A a B, ma quando torno, la barra di navigazione è aggiornata dopo. Come se fosse stato impostato in viewDidAppear .

Previsto:

La barra di navigazione dovrebbe avere il suo colore della barra di navigazione aggiornato senza indugio.

Soluzioni provate:

  • Ho visto questo post in SO e ho provato la soluzione. Ha funzionato, ma renderebbe la gestione della barra di navigazione molto più complessa e dolorosa. (in una vera app)

  • Ho provato a cambiare la barra di navigazione nel metodo ViewWillDisappear . Non ha funzionato

Di Più:

Questo è causato da una modifica dell’API ios10. Ho letto le note di rilascio , ma non è ancora chiaro cosa dovrebbe essere fatto in questo caso.

In iOS 10, UIKit ha aggiornato e unificato la gestione in background per UINavigationBar, UITabBar e UIToolbar. In particolare, le modifiche alle proprietà di sfondo di queste viste (come lo sfondo o le immagini shadow o l’impostazione dello stile della barra) possono dare il via a un passaggio di layout per la barra per risolvere il nuovo aspetto dello sfondo.

In particolare, ciò significa che i tentativi di modificare l’aspetto di sfondo di queste barre all’interno di layoutSubviews, – [UIView updateConstraints], viewWillLayoutSubviews, viewDidLayoutSubviews, updateViewConstraints o qualsiasi altro metodo chiamato in risposta al layout potrebbe causare un loop di layout.

In alcuni casi è ansible interrompere questi loop di layout assicurandosi di utilizzare sempre la stessa istanza dell’object quando sono richiesti oggetti (come UIImage o UIColor). Ma in generale dovresti evitare di farlo.

Domanda:

Quale sarebbe il modo migliore per gestire le modifiche della barra di navigazione tra diversi controller di navigazione in iOS 10?

Prova questo codice:

Nota: codice testato in Swift 3.

In ViewController A:

  override var isViewLoaded: Bool { title = "View 1" navigationController?.navigationBar.barTintColor = .blue navigationController?.navigationBar.isTranslucent = true navigationController?.navigationBar.tintColor = UIColor.white navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white] UIApplication.shared.statusBarStyle = .lightContent self.navigationController?.navigationBar.barStyle = .black // In case statusbar Light content wont work. return true } 

In ViewController B:

  override var isViewLoaded: Bool { title = "View 2" navigationController?.navigationBar.barTintColor = .green navigationController?.navigationBar.tintColor = .white navigationController?.navigationBar.isTranslucent = true navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white] return true } 

Uscita: nessun ritardo cosa mai …

inserisci la descrizione dell'immagine qui

Immagine del pattern come TintColor.

In ViewController A:

  navigationController?.navigationBar.barTintColor = UIColor(patternImage: UIImage(named: "viewOneImage.jpg")!) 

In ViewController B:

  navigationController?.navigationBar.barTintColor = UIColor(patternImage: UIImage(named: "viewTwoImage.jpg")!) 

Produzione:

inserisci la descrizione dell'immagine qui