iOS navigationBar监听返回 & 调整left/rightItem边距

监听navigationBar返回事件

很多时候我们需要监听navigationBar返回按钮的事件,但是iOS并没有提供相关回调。所以通常的做法是自定义返回按钮,比如各种箭头,但是如果我们需要原生的样式怎么办呢?那就做个比较像的按钮……

有没有更好的解决方法?答案是有的,不过不是我发现的,参见这个项目:Github,巧妙地覆写了UIViewController实现的UINavigationBarDelegate协议的一个方法:- navigationBar:shouldPopItem:,随意不要怕被审核拦下,因为并不是隐藏API。

使用方法:

  1. #import "UIViewController+BackButtonHandler.h"
  2. 实现navigationShouldPopOnBackButton方法
  3. 如果不想pop,return NO; 即可,同时可以在上面这个方法里面执行需要的代码。

在navigationBar上添加自定义按钮,是很常见的操作,比如上面所说问题的“通常”解法。但是自定义item是无法做到和默认的按钮一样靠近屏幕边缘的。通过View Hierarchy可以看到,自定义的View和旁边有一定的距离,如图:

hierarchy

界面上的效果是这样:

screenshot

这通常不是我们想要的,那怎么缩小这个间隔呢?先看下修改过后的效果图和View Hierarchy:

screenshot2

hierarchy2

做法是这样的:

修改前:

1
2
3
4
5
6
7
8
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"round"] style:UIBarButtonItemStylePlain target:self action:@selector(clickLeftItem)];

UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"round"]];
[iv addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickLeftItem)]];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:iv];

self.navigationItem.leftBarButtonItem = leftItem;
self.navigationItem.rightBarButtonItem = rightItem;

修改后:

1
2
3
4
5
6
7
8
9
10
11
UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"round"] style:UIBarButtonItemStylePlain target:self action:@selector(clickLeftItem)];

UIImageView *iv = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"round"]];
[iv addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickLeftItem)]];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:iv];

UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSpacer.width = -16;

self.navigationItem.leftBarButtonItems = @[negativeSpacer, leftItem];
self.navigationItem.rightBarButtonItem = rightItem;

通过使用UIBarButtonSystemItemFixedSpaceitems左移,使其靠近边缘。当然,rightItems也是可以的,需要注意的是需要把negativeSpacer放在第一个位置。

参考:stackoverflow