在iOS7中,如果使用了UINavigationController,那么系统自带的附加了一个从屏幕左边缘开始滑动可以实现pop的手势。但是,如果自定义了navigationItem的leftBarButtonItem,那么这个手势就会失效。解决方法有很多种
1.重新设置手势的delegate
1
|
self
.navigationController.interactivePopGestureRecognizer.delegate = (
id
<UIGestureRecognizerDelegate>)
self
;
|
2.当然你也可以自己响应这个手势的事件
1
|
[
self
.navigationController.interactivePopGestureRecognizer addTarget:
self
action:
@selector
(handleGesture:)];
|
我使用了第一种方案,继承UINavigationController写了一个子类,直接设置delegate到self。最初的版本我是让这个gesture始终可以begin
1
2
3
4
|
-(
BOOL
)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return
YES
;
}
|
但是出现很多问题,比如说在rootViewController的时候这个手势也可以响应,导致整个程序页面不响应;如果在push的同时我触发这个手势,那么会导致navigationBar错乱,甚至crash;push了多层后,快速的触发两次手势,也会错乱。尝试了种种方案后我的解决方案是加个判断,代码如下,这次运行良好了。
1
2
3
4
5
|
@interface
NavRootViewController : UINavigationController<UIGestureRecognizerDelegate,UINavigationControllerDelegate>
@property
(
nonatomic
,weak) UIViewController* currentShowVC;
@end
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
@implementation
NavRootViewController
-(
id
)initWithRootViewController:(UIViewController *)rootViewController
{
NavRootViewController* nvc = [
super
initWithRootViewController:rootViewController];
self
.interactivePopGestureRecognizer.delegate =
self
;
nvc.delegate =
self
;
return
nvc;
}
-(
void
)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(
BOOL
)animated
{
}
-(
void
)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(
BOOL
)animated
{
if
(navigationController.viewControllers.count == 1)
self
.currentShowVC = Nil;
else
self
.currentShowVC = viewController;
}
-(
BOOL
)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if
(gestureRecognizer ==
self
.interactivePopGestureRecognizer) {
return
(
self
.currentShowVC ==
self
.topViewController);
}
return
YES
;
}
@end
|
正当窃喜的时候,发现了另一个更高端的解决方案,就是参考2。使用backBarButtonItem
1
2
3
4
5
6
7
8
9
10
11
12
|
// 统一替换 back item 的图片
[
self
.navigationController.navigationBar setBackIndicatorImage:
[UIImage imageNamed:@
"CustomerBackImage"
]];
[
self
.navigationController.navigationBar setBackIndicatorTransitionMaskImage:
[UIImage imageNamed:@
"CustomerBackImage"
]];
// back item的标题 是 被将要返回的页面 所控制的,所以如果要改变当前的back item的标题,要在上一个viewcontroller里面设置
self
.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:@
""
style:UIBarButtonItemStylePlain
target:
nil
action:
nil
];
|
不过这种方案的缺点是如果你要设置 leftBarButtonItems 来更多的自定义左边的 items时,手势又会失效(或者有其他方案我还不知道*—*)。所以最后我又选择了自己的方法。
参考1 http://www.taofengping.com/2013/12/26/ios7_barbuttonitem_navigation_gesture/#.UtZ48WSSzGz
参考2 http://blog.movieos.org/post/63401593182/custom-uinavigationcontroller-back-buttons-under-ios7