يمكن أن يبدو سلوك UINavigationBar عند عبور المكدس غير متوقع وغالبًا ما تكون عربات التي تجرها الدواب. لكن في الحقيقة ، إنه كذلك! تهدف هذه المقالة إلى تحديث معرفتك بمبادئ العمل وإظهار إمكانيات تخصيص السلوك.
بعض النظريات العامة
إذا كنت على دراية ، فلا تتردد في التمرير مباشرة إلى الرسوم المتحركة.
UINavigationBar هي طريقة عرض. عادةً ما يتم التحكم في موضعه بواسطة UINavigationController ، ولكن مثل طرق العرض الأخرى ، يمكنك استخدامه بنفسك.
UINavigationItem هي فئة تصف الحالة (على غرار viewModel) لتكوين UINavigationBar. مجرد فئة مع الخصائص التي سيتم تمريرها إلى UINavigationBar.
يحتوي UINavigationBar على مصفوفة [UINavigationItem]. باستخدام طرق pushItem و popItem و setItems ، يمكنك تحريك الانتقال من حالة UINavigationBar إلى أخرى.
يحتوي كل UIViewController على عنصر ملاحة UIN. يدير UINavigationController نفسه إضافة هذه الخاصية إلى مجموعة عناصر UINavigationBar.
مزيد من التفاصيل يمكن العثور عليها هنا:
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 = trueUINavigationController 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/