Barre de navigation et animation de transition

Le comportement de UINavigationBar lors de la traversée de la pile peut sembler imprévisible et souvent bogué. Mais, en fait, ça l'est! Cet article vise à rafraßchir vos connaissances sur les principes de travail et à montrer les possibilités de personnalisation du comportement.

Une théorie générale

Si vous ĂȘtes bien informĂ©, n'hĂ©sitez pas Ă  faire dĂ©filer directement vers l'animation.

  1. UINavigationBar est une vue. En rĂšgle gĂ©nĂ©rale, sa position est contrĂŽlĂ©e par UINavigationController, mais comme les autres vues, vous pouvez l'utiliser vous-mĂȘme.

  2. UINavigationItem est une classe qui décrit l'état (similaire à viewModel) pour la configuration UINavigationBar. Juste une classe avec des propriétés qui seront transmises à UINavigationBar.

  3. UINavigationBar contient un tableau [UINavigationItem]. À l'aide des mĂ©thodes pushItem, popItem et setItems, vous pouvez animer la transition d'un Ă©tat UINavigationBar Ă  un autre.

  4. Chaque UIViewController contient un UINavigationItem. UINavigationController gĂšre lui-mĂȘme l'ajout de cette propriĂ©tĂ© Ă  la pile d'Ă©lĂ©ments UINavigationBar.

Plus de détails ici:

UINavigationBar-. :

UINavigationBar . :

  • prompt ( )

  • largeTitleDisplayMode

UINavigationBar – view, – , , .

: – navigationBar.backgroundColor, – navigationBar.barTintColor.

– backgroundColor. , backgroundColor – view -. 

prompt- .

, transition UINavigationBar . UIViewControllerAnimatedTransitioning UINavigationBar. 

: ,

safeArea . additionalSafeAreaInsets UIViewController- :

contentView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true

UINavigationController UINavigationControllerDelegate. , .

class NavigationController: UINavigationController, UINavigationControllerDelegate { }

UINavigationController-.

navigationController.delegate = navigationController

. UIViewController navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) transitionCoordinator safeArea.

guard let fromViewController = viewController.transitionCoordinator?.viewController(forKey: .from) 

else { return }

//   .     , ,  pop

let isPopped = !navigationController.viewControllers.contains(fromViewController)

 

//  ,      

viewController.transitionCoordinator?.animate { context in

    guard let from = context.viewController(forKey: .from),

          let to = context.viewController(forKey: .to)

    else { return }

    

    //   

    //      ,   safeArea 

    //     

    UIView.setAnimationsEnabled(false)

    let diff = to.view.safeAreaInsets.top - from.view.safeAreaInsets.top

    //      

    to.additionalSafeAreaInsets.top = -diff

    to.view.layoutIfNeeded()

    UIView.setAnimationsEnabled(true)

    

    //  safeArea

    to.additionalSafeAreaInsets.top = 0

    to.view.layoutIfNeeded()

    

    guard isPopped else { return }

 

    //     pop-

    //      additionalSafeAreaInsets  

    from.view.frame.origin.y = diff

    from.view.frame.size.height += max(0, -diff)

    

} completion: { context in

    guard let from = context.viewController(forKey: .from),

          let to = context.viewController(forKey: .to)

    else { return }

    

    from.additionalSafeAreaInsets.top = 0

    to.additionalSafeAreaInsets.top = 0

}

, :

– . , UINavigationBar. , , . 

, :)

: Rtishchev Evgenii https://twitter.com/katleta3000/status/1259400743771156480

https://stackoverflow.com/questions/39515313/animate-navigation-bar-bartintcolor-change-in-ios10-not-working

navigation bar: https://www.programmersought.com/article/1594185256/




All Articles