web-dev-qa-db-fra.com

UINavigationBar change les couleurs en poussant

J'utilise 2 couleurs de teinte de barre différentes à UINavigationBar dans différentes vues. Je change de couleur avec cette méthode dans les deux vues:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.barTintColor = COLOR
}

Lorsque je tape sur le bouton de retour, la couleur du bouton n’est pas modifiée en douceur (vous pouvez voir clignoter à la dernière seconde).

 Visual bug

Mais tout va bien si vous faites simplement glisser la vue vers l'arrière au lieu d'appuyer sur le bouton Retour.

 No visual bug

Comment faire une transition en douceur dans les deux situations?

18
Vasily

J'ai codé la solution finale qui semble la plus confortable à utiliser (vous n'avez pas besoin d'utiliser beaucoup de substitutions dans vos propres contrôleurs de vue). Il fonctionne parfaitement sous iOS 10 et est facilement adoptable à ses propres fins.

GitHub

Vous pouvez vérifier GitHub Gist pour connaître le code complet de la classe et un guide plus détaillé. Je ne publierai pas le code complet ici car Stackoverflow n'est pas conçu pour stocker beaucoup de code.

Usage

Téléchargez le fichier Swift pour GitHub. Pour que cela fonctionne, utilisez simplement ColorableNavigationController au lieu de UINavigationController et adoptez les contrôleurs de vue enfant nécessaires au protocole NavigationBarColorable.

Exemple:

class ViewControllerA: UIViewController, NavigationBarColorable {
    public var navigationBarTintColor: UIColor? { return UIColor.blue }

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Push", style: .plain, target: self, action: #selector(self.showController))
    }

    func showController() {
        navigationController?.pushViewController(ViewControllerB(), animated: true)
    }
}

class ViewControllerB: UIViewController, NavigationBarColorable {
    public var navigationBarTintColor: UIColor? { return UIColor.red }
}

let navigationController = ColorableNavigationController(rootViewController: ViewControllerA())
9
Vasily

Je me demande simplement. Dans le même but, j'utilise UINavigationControllerDelegate. Dans navigationController(_:willShow:), je lance l'animation à l'aide de transitionCoordinator?.animate(alongsideTransition:completion:). Cela fonctionne très bien lorsque vous appuyez sur de nouveaux contrôleurs, mais la pop ne le fait pas. 

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
  let dst = viewController as! ViewController
  guard animated else {
    navigationController.navigationBar.barTintColor = dst.navigationBarColor
    navigationController.navigationBar.tintColor = dst.tintColor
    navigationController.navigationBar.barStyle = dst.barStyle
    return
  }

  navigationController.transitionCoordinator?.animate(alongsideTransition: { context in
    navigationController.navigationBar.barTintColor = dst.navigationBarColor
    navigationController.navigationBar.tintColor = dst.tintColor
    navigationController.navigationBar.barStyle = dst.barStyle
  }, completion: { context in
    if context.isCancelled {
      let source = context.viewController(forKey: UITransitionContextViewControllerKey.from) as! ViewController
        navigationController.navigationBar.barTintColor = source.navigationBarColor
        navigationController.navigationBar.tintColor = source.tintColor
        navigationController.navigationBar.barStyle = source.barStyle
    }
})

Voyez-vous une raison pour laquelle cela devrait fonctionner avec des push mais pas des pops?

 Push and pop

0
olejnjak