iOS11 导航栏UIBarButtonItem自定义按钮偏移

作者: ivylee_mr | 来源:发表于2017-09-25 10:40 被阅读3730次

前言

最近iOS11 发放出来已经有一段时间了,不得不说每到9月,都是果粉兴奋,iOS代码狗抓狂的时候。。。。
iOS 11 放出来,于是各种各样的坑也就跟预留好了。。。
其中一个比较烦人的坑就是导航栏UIBarButtonItem自定义按钮偏移 在iOS11 系统下 通过以前的UIBarButtonSystemItemFixedSpace的方式已经无法修复了。。。。。
所以我们也是尝试了各种方法去填iOS11给我们挖的坑。。。

iOS11 和iOS11效果图如下:(响应范围可以自己亲测调试)

**左边是iOS11 5S, 右边是iOS10 SE**

目前网上比较流行的方法

方法一:iOS11 导航栏按钮位置问题的解决

作者:spicyShrimp
http://blog.csdn.net/spicyShrimp/article/details/77891717
附上地址,大家可以去看一下,利用各种黑魔法解决了这个bug,不论是修复点击范围,还是视图布局都做到了完美解决,但问题就是这个方案的代价比较大。

方法一:iOS11导航栏自定义按钮偏移问题

作者:可可西里的藏野驴
http://blog.csdn.net/guo4114/article/details/78053025
这个方法只是解决了视图问题,但还有一个实质问题尚未解决,就是返回按键的点击位置依旧没有改变,大家可以试一试。

我的方法

具体思路是: 先修改button 的视图布局,再修改button 的响应范围。

第一步:适配系统,iOS11 系统以下,依旧保持不变

 UIButton *backButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
    [backButton setNormalImage:[UIImage imageNamed:@"mine_back_cheng"]];
    [backButton setHighlightedImage:[UIImage imageNamed:@"mine_back_white"]];
    [backButton addClickEventWithBlock:clickHandler];
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithCustomView:backButton];
    //配置返回按钮距离屏幕边缘的距离
    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    spaceItem.width = -10.0f;
    self.navigationItem.leftBarButtonItems = @[spaceItem,backItem];

第二步:iOS11 系统下,修改UI布局

依旧在上面的代码进行系统区分,修改布局

 UIButton *backButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
    [backButton setNormalImage:[UIImage imageNamed:@"mine_back_cheng"]];
    [backButton setHighlightedImage:[UIImage imageNamed:@"mine_back_white"]];
    [backButton addClickEventWithBlock:clickHandler];
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithCustomView:backButton];
    //配置返回按钮距离屏幕边缘的距离
    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    spaceItem.width = -10.0f;
// iOS 11 系统,将Button的内容 和 图片根具体需求进行便处理
if (([[[UIDevice currentDevice] systemVersion] floatValue] >= 11.0)) {
        backButton.contentEdgeInsets =UIEdgeInsetsMake(0, -15,0, 0);
        backButton.imageEdgeInsets =UIEdgeInsetsMake(0, -15,0, 0);
    }
    self.navigationItem.leftBarButtonItems = @[spaceItem,backItem];

第三步:修改布局之后,修改UIBarButtonItem 的响应范围。

        backButton.contentEdgeInsets =UIEdgeInsetsMake(0, -15,0, 0);
        backButton.imageEdgeInsets =UIEdgeInsetsMake(0, -15,0, 0);

只是修改了 返回Button 的视图,没有对返回Button的实际响应范围进行修改。所以下面的实际修改范围 需要加入这个一段代码,来修改button的响应范围。

       // 修改返回**Button**的响应范围 ,往左边扩大6 个胆怯
        backButton.hitEdgeInsets =UIEdgeInsetsMake(0, -6, 0, 0);

WHAT?? hitEdgeInsets button 有这个东西吗???

确实没有。这个只是我们给UIButton利用分类Category,添加的一个属性,来修改button 的响应范围。
具体代码和方式参考:
UIButton 扩大按钮的响应区域(runtime)


最终代码:

由于修改的东西不多,我这里就把代码贴出来就好了:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"注册";
    kDefineWeakSelf;
    [self showCustomLeftImgBarButton:^(UIButton *button) {
        [weakSelf.navigationController popViewControllerAnimated:YES];
    }];
    // Do any additional setup after loading the view.
}

-(void)showCustomLeftImgBarButton:(void (^)(UIButton *button))clickHandler{
    UIButton *backButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
    [backButton setNormalImage:[UIImage imageNamed:@"mine_back_cheng"]];
    [backButton setHighlightedImage:[UIImage imageNamed:@"mine_back_white"]];
    [backButton addClickEventWithBlock:clickHandler];
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc]initWithCustomView:backButton];
    //配置返回按钮距离屏幕边缘的距离
    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
    spaceItem.width =  kIOS11_OR_LATER? 0:fixSpacing;
    if (kIOS11_OR_LATER) {
        backButton.contentEdgeInsets =UIEdgeInsetsMake(0, -15,0, 0);
        backButton.imageEdgeInsets =UIEdgeInsetsMake(0, -15,0, 0);
        backButton.hitEdgeInsets =UIEdgeInsetsMake(0, -6, 0, 0);
    }
    self.navigationItem.leftBarButtonItems = @[spaceItem,backItem];
}

UIButton利用分类Category,添加的一个属性,来修改button 的响应范围。
具体代码和方式参考:
UIButton 扩大按钮的响应区域(runtime)

相关文章

网友评论

  • spicyShrimp:新的解决方案
    http://blog.csdn.net/spicyShrimp/article/details/78201042
    ivylee_mr:@spicyShrimp 新的方案很强大。
  • 机智的猪:mark
    看看以后有更好的解决办法没
  • GoogleOriented:你好,请问leftBarButtonItem离屏幕边缘的那一小段距离,即使修改响应区域也无法点击吗
    ivylee_mr:@脱脂棉纱布毛毯棉布团是的,
  • ldldlkdldld:对于右侧的导航栏按钮,通过添加一个customview,然后将button作为customview的子view能够解决视觉需求,但是扩展按钮热区也没办法解决按钮右侧点击无响应的问题。感觉很坑啊。
    ldldlkdldld:@ivylee_mr 嗯,打算这么做了吗还是全部自己掌控比较好,苹果太坑了
    ivylee_mr:@懒周 是的,目前最好的解决办法就是导航栏全部隐藏^_^^_^自定义一个view
  • 面试小集:点击范围没有扩大呀
    面试小集:@ivylee_mr 我想了一种方法: 还能不影响点击范围,基本思路就是重写: drawReact:
    http://www.jianshu.com/p/383cdad95a32
    面试小集:@ivylee_mr 好吧。谢了
    ivylee_mr:iOS 11 导航栏 最左边 和 最 右边 有一块区域大概15个 像素 无论你如何修改,这一块位置都不能响应。。。。
    根治方法只能自定义一个View 来写Navi。
  • 管家頗:位置根本没变
    ivylee_mr:@管家頗 图片位置这个是左边的情况,你根据你的具体情况修改按钮
    管家頗:@ivylee_mr 图片位置
    ivylee_mr:图片位置吗?还是响应位置?
  • iOS白水:initWithCustomView:backButton。 有验证再5s。点击区域变小的问题么? 我刚发现。坑。
    ivylee_mr:UIButton 扩大按钮的响应区域(runtime)这篇文章 上面有代码,直接可以用
    iOS白水:@ivylee_mr 你不是扩大点击区域了么? 有qq么? 一起交流一下。 取代是不可能的。
    ivylee_mr:刚测试了下 ,确实有,不光是5S,所有的iOS11 系统,左边的有一块区域都是不让点击的。。。
    如果要解决这个问题,只能自定义一个UIView 去取代这个了导航栏了
  • spicyShrimp:很棒的思路,另外,感谢你的建议,你的这个思路是最早在beta出来时候就有的之所以没有写出来是因为我之前写的项目中有的部分不是按钮(虽然很少见),没有办法修改内容偏移,设置整个视图的位置偏移就需要单独再设置,所以就放弃了,我现在的这个解决方案也只是比较适合我的项目的一个对应的折中方案.
    我是想找一个比较完美的替换方案,不仅仅是按钮,其能够包括任何视图控件,虽然目前没有什么更好的思路
    如果还有更好的思路,可以一起探讨优化
    ivylee_mr:@spicyShrimp 你那种方法 才是正道,我这只是歪路子=。=

本文标题: iOS11 导航栏UIBarButtonItem自定义按钮偏移

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