Bilah navigasi dan animasi transisi

Perilaku UINavigationBar saat menavigasi tumpukan bisa tampak tidak dapat diprediksi dan sering bermasalah. Tapi, nyatanya, itu benar! Artikel ini dimaksudkan untuk menyegarkan pengetahuan tentang prinsip kerja dan menunjukkan kemungkinan untuk menyesuaikan perilaku.

Beberapa teori umum

Jika Anda berpengetahuan luas, silakan gulir langsung ke animasi.

  1. UINavigationBar adalah sebuah tampilan. Biasanya, posisinya dikontrol oleh UINavigationController, tetapi seperti tampilan lain, Anda dapat menggunakannya sendiri.

  2. UINavigationItem adalah kelas yang mendeskripsikan status (mirip dengan viewModel) untuk konfigurasi UINavigationBar. Hanya kelas dengan properti yang akan diteruskan ke UINavigationBar.

  3. UINavigationBar berisi larik [UINavigationItem]. Dengan menggunakan metode pushItem, popItem, dan setItems, Anda dapat menganimasikan transisi dari satu status UINavigationBar ke yang lain.

  4. Setiap UIViewController berisi UINavigationItem. UINavigationController itu sendiri mengelola penambahan properti ini ke tumpukan item UINavigationBar.

Detail lebih lanjut dapat ditemukan di sini:

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