zoukankan      html  css  js  c++  java
  • 关于backBarButtonItem的N种方法

    今天在做项目的时候遇到一点小问题,后来自己解决了,也顺便思考了一下更深层次的东西,在这里分享一下~~

    替换返回按钮的文字

    很多app的要求所有的返回按钮的title都是“返回”,如果上一层题目文字太多,下一层的返回按钮文字就会显示不完全,而且这样可以使软件显得整洁。

    方法一:

    最普通的想法,A界面的navigationItem.backBarButtonItem修改的是B(A的下一级)界面的返回按钮,所以可以写一个BaseViewController,让所有的UIViewController继承它,像这样

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:nil];
    }

    方法二:

    思路是:在开启程序时,使用Method Swizzling,将系统自带的backBarButtonItem方法替换成我们自定义的方法。

    具体实现就是创建个 UINavigationItem + BackItem 的类别,当系统执行+load方法时,将backBarButtonItem方法和myCustomBackButton方法交换,利用iOS关联方法(objc_getAssociatedObject,objc_setAssociatedObject)static区创建个backItemButton用来展示。这个方法的好处就是将类别导入到工程里不用任何代码就可以实现,上代码吧:

    +(void)load{
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            Method originalMethodImp = class_getInstanceMethod(self, @selector(backBarButtonItem));
            Method destMethodImp = class_getInstanceMethod(self, @selector(myCustomBackButton));
            method_exchangeImplementations(originalMethodImp, destMethodImp);
        });
    }
    
    static char kCustomBackButtonKey;
    
    -(UIBarButtonItem *)myCustomBackButton{
        UIBarButtonItem *item = [self myCustomBackButton];
        if (item) {
            return item;
        }
        item = objc_getAssociatedObject(self, &kCustomBackButtonKey);
        if (!item) {
            item = [[UIBarButtonItem alloc] initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:nil action:NULL];
            objc_setAssociatedObject(self, &kCustomBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        return item;
    }
    
    - (void)dealloc
    {
        objc_removeAssociatedObjects(self);
    }

    返回按钮只显示自定义图片

    方法一:

    最开始我的方案是实现UINavigationController的代理判断是否是栈底,如果不是就修改leftBarButtonItem的样式。

    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        UIViewController *root = navigationController.viewControllers[0];
        
        if (root != viewController) {
            UIBarButtonItem *itemleft = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"backBtn"] style:UIBarButtonItemStylePlain target:self action:@selector(popAction:)];
            viewController.navigationItem.leftBarButtonItem = itemleft;
        }
    }
    
    
    - (void)popAction:(UIBarButtonItem *)barButtonItem
    {
        [self.navigationController popViewControllerAnimated:YES];
    }

    iOS7.0出了之后,这并不是一个好的解决方案。因为iOS7.0之后如果把backItemButton替换成leftItemButon,interactivePopGestureRecognizer手势就没有了。虽然可以使用

    self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;

    方法二:

    这个方法和上边‘替换返回按钮的文字’方法二大致一样,这句话要替换:

    item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"back"] style:UIBarButtonItemStylePlain target:nil action:nil];

    这句话要加上,用来去除系统自带的返回按钮上的尖脚号。

    [[UINavigationBar appearance] setBackIndicatorImage:[[UIImage alloc]init]];
    [[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:[[UIImage alloc] init]];

    技术上的问题其实有好多方法可以去解决,而且在效率相差不大的情况下,关键是我们的使用习惯,所以整理一下现在的思路,方便以后使用。

  • 相关阅读:
    php内存管理机制、垃圾回收机制
    Redis 3.2.1集群搭建
    centos开启IPV6配置方法
    /etc/hosts.allow和/etc/hosts.deny详解
    3元购买微信小程序解决方案一个月
    linux下使用ntfs-3g挂载NTFS出错
    腾讯云微信小程序域名变更指南
    nginx开启gzip压缩
    centos 7使用yum安装docker容器
    linux中启动网卡报错:Bringing up interface eth1: Error: Connection activation failed
  • 原文地址:https://www.cnblogs.com/LeoTai/p/5456705.html
Copyright © 2011-2022 走看看