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.
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.
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.
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.
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:
https://developer.apple.com/documentation/uikit/uinavigationbar
https://developer.apple.com/documentation/uikit/uinavigationitem
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
navigation bar: https://www.programmersought.com/article/1594185256/