美文网首页
iOS 导航栏-返回按钮-自定义

iOS 导航栏-返回按钮-自定义

作者: 光之盐汽水 | 来源:发表于2019-04-26 15:12 被阅读0次

    在开发过程中,我们经常遇到使用系统导航栏的功能,如何更改返回按钮的样式呢?

    一、更改返回按钮图片

    // 更换返回按钮的图片
    UIImage *backButtonImage = [[UIImage imageNamed:@"bt_navigationBar_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        
    [UINavigationBar appearance].backIndicatorTransitionMaskImage = backButtonImage;
    [UINavigationBar appearance].backIndicatorImage = backButtonImage;
    
    
    // 返回按钮的文字置空(在UINavigationController的子类或者分类categary)中添加该方法
    - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item {
        UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
        item.backBarButtonItem = back;
        return YES;
    }
    

    二、重写返回按钮

    重写返回按钮一般是添加leftBarButtonItems。如果导航栏添加了leftBarButtonItems之后,会自动隐藏返回按钮backBarButtonItem。

    // 返回按钮
    UIBarButtonItem *backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"bt_navigationBar_back"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(backAction)];
    self.navigationItem.leftBarButtonItem = backBarButtonItem;
    
    // 返回按钮的回调方法
    - (void)backAction {
    }
    

    三、拦截系统导航栏的返回按钮监听事件

    当我们使用了系统的导航栏时,默认点击返回按钮是 pop 回上一个界面。但是在有时候,我们需要在点击导航栏的返回按钮时不一定要 pop 回上一界面,可能是其他的页面,我们需要拦截返回按钮的pop操作。

    1、重写返回按钮
    具体操作查看上面“二、重写返回按钮”。
    缺点:若重写了某个界面的返回按钮,感觉应用整体就不统一了。而且每有一个界面有这个需求都需要重新自定义一个返回按钮,显得不优雅,工作繁琐。

    2、为 UINavigationController 添加 category

    //item将要push的时候调用,返回NO,则不能push
    - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPushItem:(UINavigationItem *)item; // called to push. return NO not to.
    
    //item已经push后调用
    - (void)navigationBar:(UINavigationBar *)navigationBar didPushItem:(UINavigationItem *)item;    // called at end of animation of push or immediately if not animated
    
    //item将要pop时调用,返回NO,不能pop  
    - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item;  // same as push methods
    
    //item已经pop后调用 
    - (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item;
    

    我们可以为 UINavigatonController 创建一个 Category,来定制navigationBar: shouldPopItem: 的逻辑。

    // UIViewController+BackButtonHandler.h
    @protocol BackButtonHandlerProtocol <NSObject>
    @optional
    // 重写下面的方法以拦截导航栏返回按钮点击事件,返回 YES 则 pop,NO 则不 pop
    -(BOOL)navigationShouldPopOnBackButton;
    @end
    
    @interface UIViewController (BackButtonHandler) <BackButtonHandlerProtocol>
    
    @end
    
    // UIViewController+BackButtonHandler.m 
    @implementation UIViewController (BackButtonHandler)
    
    @end
    
    @implementation UINavigationController (ShouldPopOnBackButton)
    
    - (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
    
        if([self.viewControllers count] < [navigationBar.items count]) {
            return YES;
        }
    
        BOOL shouldPop = YES;
        UIViewController* vc = [self topViewController];
        if([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) {
            shouldPop = [vc navigationShouldPopOnBackButton];
        }
    
        if(shouldPop) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self popViewControllerAnimated:YES];
            });
        } else {
            // 取消 pop 后,复原返回按钮的状态
            for(UIView *subview in [navigationBar subviews]) {
                if(0. < subview.alpha && subview.alpha < 1.) {
                    [UIView animateWithDuration:.25 animations:^{
                        subview.alpha = 1.;
                    }];
                }
            }
        }
        return NO;
    }
    

    使用时,只需要在需要拦截返回按钮事件的控制器中,应用#import "UIViewController+BackButtonHandler.h",并重写-(BOOL)navigationShouldPopOnBackButton方法即可。

    - (BOOL)navigationShouldPopOnBackButton{
       //拦截返回按钮后做的处理
    
        //返回NO(一定要返回NO)
        return NO;
    }
    

    相关文章

      网友评论

          本文标题:iOS 导航栏-返回按钮-自定义

          本文链接:https://www.haomeiwen.com/subject/esrfnqtx.html