前言(可略)
有的頁面有導航欄,有的頁面又不要導航欄,同時又想手勢返回動畫流暢。
或許會采用以下方法:
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
self.navigationController.navigationBarHidden = YES;
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.navigationController.navigationBarHidden = NO;
}
這個方法有兩個問題:1.方法繁瑣;2.B界面手勢返回時,B界面導航欄消失;
對與問題2,可以改用下面解決:
[self.navigationController setNavigationBarHidden:hiden animated:animated];
但又引入一個問題,當AB界面都隱藏導航欄時,導航欄有消失和出現的動畫。如何解決就是我思考的問題了。
解決方案
step1:通過運行時添加屬性shouldNavigationBarHidden
,標識控制器是否需要隱藏導航欄
step2:自定義導航欄,對比shouldNavigationBarHidden
與導航欄navigationBarHidden
,不一致時隱藏導航欄
使用方法:
在ViewController的viewDidLoad
中設置
self.shouldNavigationBarHidden
即可。
注意:push
前設置view.backgroundColor
等view
相關內容會導致viewDidLoad
提前的順序問題
代碼
@interface UIViewController (NavigationBarHidden)
/// 是否隱藏導航欄。默認NO。
@property (nonatomic , assign) BOOL shouldNavigationBarHidden;
@end
@interface HideNavigationController : UINavigationController<UINavigationControllerDelegate>
@end
#import "UIViewController+NavigationBarHidden.h"
#import <objc/runtime.h>
@implementation UIViewController (NavigationBarHidden)
- (BOOL)shouldNavigationBarHidden{
return [objc_getAssociatedObject(self, @selector(shouldNavigationBarHidden)) boolValue];
}
- (void)setShouldNavigationBarHidden:(BOOL)shouldNavigationBarHidden{
objc_setAssociatedObject(self, @selector(shouldNavigationBarHidden), @(shouldNavigationBarHidden), OBJC_ASSOCIATION_ASSIGN);
}
@end
@implementation HideNavigationController
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = self;
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
if (self.viewControllers.count > 0) {
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (viewController.shouldNavigationBarHidden != self.navigationBarHidden) {
[self setNavigationBarHidden:viewController.shouldNavigationBarHidden animated:animated];
}
}
@end
對于隱藏了導航欄的控制器,手勢返回也消失了。可自定義手勢,在邊緣開始滑動時調用interactivePopGestureRecognizer
方法。可參考 iOS導航欄隱藏透明處理 && 側滑返回手勢