iOS_小蟹专题iOS无法删除的专题

iOS隐藏导航栏

2017-08-10  本文已影响439人  平原河流

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。

以上就是我整理的隐藏导航栏的三种方法。

上一篇下一篇

猜你喜欢

热点阅读