Barra de navegación y animación de transición

El comportamiento de UINavigationBar cuando se navega por la pila puede parecer impredecible y, a menudo, con errores. ¡Pero, de hecho, lo es! Este artículo tiene como objetivo refrescar su conocimiento de los principios del trabajo y mostrar las posibilidades de personalizar el comportamiento.

Alguna teoría general

Si tiene conocimientos, no dude en desplazarse directamente a la animación.

  1. UINavigationBar es una vista. Normalmente, su posición está controlada por UINavigationController, pero al igual que otras vistas, puede usarlo usted mismo.

  2. UINavigationItem es una clase que describe el estado (similar al viewModel) para la configuración de UINavigationBar. Solo una clase con propiedades que se pasarán a UINavigationBar.

  3. UINavigationBar contiene una matriz [UINavigationItem]. Con los métodos pushItem, popItem y setItems, puede animar la transición de un estado UINavigationBar a otro.

  4. Cada UIViewController contiene un UINavigationItem. El propio UINavigationController administra la adición de esta propiedad a la pila de elementos UINavigationBar.

Más detalles se pueden encontrar aquí:

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