使用setNavigationBarHidden:animated:方法直接處理,跳轉(zhuǎn)的時(shí)候有個(gè)跳轉(zhuǎn)很丑勘畔。這個(gè)就不說了。
FDFullscreenPopGesture
我很喜歡用。
給UIViewController添加一個(gè)設(shè)置隱藏導(dǎo)航欄的屬性af_prefersNavigationBarHidden:
// MARK: - 給UIViewController添加af_prefersNavigationBarHidden屬性
@implementation UIViewController (HandlerNavigationBar)
- (BOOL)af_prefersNavigationBarHidden
{
return [objc_getAssociatedObject(self, _cmd) boolValue];
}
- (void)setLsl_prefersNavigationBarHidden:(BOOL)hidden
{
objc_setAssociatedObject(self, @selector(af_prefersNavigationBarHidden), @(hidden), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
hook UIViewController的viewWillAppear:方法,并在此方法中執(zhí)行已經(jīng)存好的代碼塊:
typedef void(^_LSLViewControllerWillAppearInjectBlock)(UIViewController *viewController, BOOL animated);
@interface UIViewController (HandlerNavigationBarPrivate)
@property(nonatomic, copy) _LSLViewControllerWillAppearInjectBlock af_willAppearInjectBlock;
@end
// MARK: - 替換UIViewController的viewWillAppear方法苛骨,在此方法中,執(zhí)行設(shè)置導(dǎo)航欄隱藏和顯示的代碼塊苟呐。
@implementation UIViewController (HandlerNavigationBarPrivate)
+ (void)load
{
Method orginalMethod = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method swizzledMethod = class_getInstanceMethod(self, @selector(af_viewWillAppear:));
method_exchangeImplementations(orginalMethod, swizzledMethod);
}
- (void)af_viewWillAppear:(BOOL)animated
{
[self af_viewWillAppear:animated];
if (self.af_willAppearInjectBlock) {
self.af_willAppearInjectBlock(self, animated);
}
}
- (_AFViewControllerWillAppearInjectBlock)af_willAppearInjectBlock
{
return objc_getAssociatedObject(self, _cmd);
}
- (void)setaf_willAppearInjectBlock:(_AFViewControllerWillAppearInjectBlock)block
{
objc_setAssociatedObject(self, @selector(af_willAppearInjectBlock), block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end
hook住navigationController的pushViewController:animated:及setViewControllers:animated:方法痒芝,當(dāng)控制器被壓入棧中的時(shí)候,預(yù)存設(shè)置隱藏和顯示導(dǎo)航欄的代碼塊到即將顯示的控制器中牵素,備控制器調(diào)用:
// MARK: - 替換UINavigationController的pushViewController:animated:方法严衬,在此方法中去設(shè)置導(dǎo)航欄的隱藏和顯示
@implementation UINavigationController (NavigationBar)
+ (void)load
{
Method originMethod = class_getInstanceMethod(self, @selector(pushViewController:animated:));
Method swizzedMethod = class_getInstanceMethod(self, @selector(af_pushViewController:animated:));
method_exchangeImplementations(originMethod, swizzedMethod);
Method originSetViewControllersMethod = class_getInstanceMethod(self, @selector(setViewControllers:animated:));
Method swizzedSetViewControllersMethod = class_getInstanceMethod(self, @selector(af_setViewControllers:animated:));
method_exchangeImplementations(originSetViewControllersMethod, swizzedSetViewControllersMethod);
}
- (void)af_pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// Handle perferred navigation bar appearance.
[self af_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController];
// Forward to primary implementation.
[self af_pushViewController:viewController animated:animated];
}
- (void)af_setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated
{
// Handle perferred navigation bar appearance.
for (UIViewController *viewController in viewControllers) {
[self af_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController];
}
// Forward to primary implementation.
[self af_setViewControllers:viewControllers animated:animated];
}
- (void)af_setupViewControllerBasedNavigationBarAppearanceIfNeeded:(UIViewController *)appearingViewController
{
if (!self.af_viewControllerBasedNavigationBarAppearanceEnabled) {
return;
}
// 即將被調(diào)用的代碼塊
__weak typeof(self) weakSelf = self;
_afViewControllerWillAppearInjectBlock block = ^(UIViewController *viewController, BOOL animated){
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf setNavigationBarHidden:viewController.af_prefersNavigationBarHidden animated:animated];
}
};
// 給即將顯示的控制器,注入代碼塊
appearingViewController.af_willAppearInjectBlock = block;
// 因?yàn)椴皇撬械亩际峭ㄟ^push的方式笆呆,把控制器壓入stack中请琳,也可能是"-setViewControllers:"的方式,所以需要對(duì)棧頂控制器做下判斷并賦值赠幕。
UIViewController *disappearingViewController = self.viewControllers.lastObject;
if (disappearingViewController && !disappearingViewController.af_willAppearInjectBlock) {
disappearingViewController.af_willAppearInjectBlock = block;
}
}
- (BOOL)af_viewControllerBasedNavigationBarAppearanceEnabled
{
NSNumber *number = objc_getAssociatedObject(self, _cmd);
if (number) {
return number.boolValue;
}
self.af_viewControllerBasedNavigationBarAppearanceEnabled = YES;
return YES;
}
- (void)setaf_viewControllerBasedNavigationBarAppearanceEnabled:(BOOL)enabled
{
SEL key = @selector(af_viewControllerBasedNavigationBarAppearanceEnabled);
objc_setAssociatedObject(self, key, @(enabled), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end