UINavigationController和UITabBarController是iOS开发中常用的两种视图控制器,主要用来控制UI界面流程跳转。
在开发过程中,经常会遇到导航栏和标签栏,以及工具栏的显示和隐藏问题。
本文主要介绍导航栏的显示与隐藏问题。
以下是我整理的与导航栏显示与隐藏相关的控件组织图:
UINavigationController
通过上图可以看出:
1、UINavigationController继承于UIViewController;
2、UINavigationController包含viewControllers(UIViewController数组)、UINavigationBar、UIToolbar;
3、UINavigationBar管理items(UINavigationItem数组);
4、UIViewController包含UINavigationItem。
下图能更好的理解UINavigationController组织结构
UINavigationController
以下介绍三种隐藏导航栏方法:
方法一:
@property(nonatomic,getter=isNavigationBarHidden) BOOL navigationBarHidden;
- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated;
@property(nonatomic,readonly) UINavigationBar *navigationBar;
使用UINavigationController的navigationBarHidden属性获取隐藏导航方法。常用于以下方法中
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
当然还有实现UINavigationControllerDelegate,在代理方法中通过判断showViewController类型,来控制显示。
// Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
这种隐藏方式在滑动过程中(iOS 7以后),会出现过渡不自然现象。(现不建议使用)
方法二:
使用UINavigationController+FDFullscreenPopGesture
该类重写了UINavigationController的+ (void)load;
方法。
具体可参照以下代码:
+ (void)load
{
// Inject "-pushViewController:animated:"
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(pushViewController:animated:);
SEL swizzledSelector = @selector(fd_pushViewController:animated:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (success) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
运用了runtime技术,在执行-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
时,执行- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated;
,以此来解决滑动过程中,过渡不自然问题。
该方法有一个不算缺陷的缺陷,就是一个工程只能只能置换一次。
如果你在一个SDK中用到了该技术(修改类别名),并且另一个工程引入了该SDK,并且也使用了该技术。会造成滑动不自然。当然,你可以把该技术单独提出来,供SDK和工程共同引用,这样就可以解决问题了。
方法三:
通过文章刚开始介绍的UINavigationController组织图,可发现UINavigationController中只包含一个UINavigationBar。那么我们可以从UINavigationBar直接入手。
self.edgesForExtendedLayout = UIRectEdgeTop;
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
if ([self.navigationController.navigationBar respondsToSelector:@selector(shadowImage)]) {
[self.navigationController.navigationBar setShadowImage:[UIImage new]];
}
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.alpha = 0.0;
self.navigationController.navigationBar.backItem.hidesBackButton = YES;
self.navigationController.navigationItem.hidesBackButton = YES;
self.navigationItem.hidesBackButton = YES;
该方法是直接控制UINavigationBar,使其背景图片、阴影图片、背景色、navigationItem等,以达到类似- (void)setNavigationBarHidden:(BOOL)hidden animated:(BOOL)animated;
效果。
常用于以下方法中
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
当然还有实现UINavigationControllerDelegate,在代理方法中通过判断showViewController类型,来控制显示。
// Called when the navigation controller shows a new top view controller via a push, pop or setting of the view controller stack.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
这种方法好处是直接控制UINavigationBar,不好的地方是调用的方法过多,还要考虑viewControllers中的navigationItem。
以上就是我整理的隐藏导航栏的三种方法。
网友评论