Navigationsleiste und Übergangsanimation

Das Verhalten der UINavigationBar beim Durchlaufen des Stapels kann unvorhersehbar und häufig fehlerhaft erscheinen. Aber tatsächlich ist es das! Dieser Artikel soll das Wissen über die Arbeitsprinzipien auffrischen und die Möglichkeiten zur Anpassung des Verhaltens aufzeigen.

Eine allgemeine Theorie

Wenn Sie sich auskennen, können Sie direkt zur Animation scrollen.

  1. UINavigationBar ist eine Ansicht. Normalerweise wird seine Position vom UINavigationController gesteuert, aber wie bei anderen Ansichten können Sie ihn selbst verwenden.

  2. UINavigationItem ist eine Klasse, die den Status (ähnlich dem viewModel) für die UINavigationBar-Konfiguration beschreibt. Nur eine Klasse mit Eigenschaften, die an die UINavigationBar übergeben werden.

  3. Die UINavigationBar enthält ein Array [UINavigationItem]. Mit den Methoden pushItem, popItem und setItems können Sie den Übergang von einem UINavigationBar-Status in einen anderen animieren.

  4. Jeder UIViewController enthält ein UINavigationItem. Der UINavigationController selbst verwaltet das Hinzufügen dieser Eigenschaft zum Stapel von UINavigationBar-Elementen.

Weitere Details finden Sie hier:

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