1、自定义Back按钮
iOS中很多时候我们都会自定义返回按钮,也是一件easy的事,类似如下:
// 返回按钮
1 - (void)showNavBackButton
2 {
3 UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
4 [backButton addTarget:self action:@selector(backButtonAction:)
5 forControlEvents:UIControlEventTouchUpInside];
6 [backButton setBackgroundImage:[UIImage imageNamed:@"00_back_button"]
7 forState:UIControlStateNormal];
8 [backButton setTitle:kLoc(@"Back") forState:UIControlStateNormal];
9 [backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 5, 1, 0)];
10 backButton.titleLabel.font = kMediumFont(12);
11 backButton.frame = CGRectMake(0, 0, 51, 31);
12 self.navigationItem.leftBarButtonItem
13 = [[UIBarButtonItem alloc] initWithCustomView:backButton];
14 }
但是,这样在iOS7下Pop interactive gesture就不好使了。
这里 Here 有一个解决方法。
但是,测试发现在栈中推入一个controller后,快速向左平滑,将会引起崩溃。
查看崩溃日志,发现如下信息:
?
1 |
|
2、解决Pop interactive gesture问题
优化的解决方案是简单的让NavigationController自己成为响应的接受者,最好用一个UINavigationController的子类。
1)在过渡的时候禁用interactivePopGestureRecognizer
2)当新的视图控制器加载完成后再启用,建议使用UINavigationController的子类操作
// 自定义NavigationController
1 @interface DCBaseNavigationController ()
2 <
3 UINavigationControllerDelegate,
4 UIGestureRecognizerDelegate
5 >
6 @end
7
8 @implementation DCBaseNavigationController
9
10 - (void)dealloc
11 {
12 self.interactivePopGestureRecognizer.delegate = nil;
13 self.delegate = nil;
14
15 [super dealloc];
16 }
17
18 #pragma mark - View lifecycle
19
20 - (void)viewDidLoad
21 {
22 [super viewDidLoad];
23 // Do any additional setup after loading the view.
24
25 if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
26 self.interactivePopGestureRecognizer.delegate = self;
27 self.delegate = self;
28 }
29 }
30
31 - (void)didReceiveMemoryWarning
32 {
33 [super didReceiveMemoryWarning];
34 // Dispose of any resources that can be recreated.
35 }
36
37 #pragma mark - Override
38
39 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
40 {
41 // Hijack the push method to disable the gesture
42 if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
43 self.interactivePopGestureRecognizer.enabled = NO;
44 }
45
46 [super pushViewController:viewController animated:animated];
47 }
48
49 #pragma mark - UINavigationControllerDelegate
50
51 - (void)navigationController:(UINavigationController *)navigationController
52 didShowViewController:(UIViewController *)viewController
53 animated:(BOOL)animate
54 {
55 if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
56 navigationController.interactivePopGestureRecognizer.enabled = YES;
57 }
58 }
59
60 @end
3、Pop interactive gesture冲突,造成页面假死问题
我遇到的情况是,Push/Pop页面时,没有立即得到想要的效果,页面没有显出出来,NavigationController的didShowViewController:回调方法也没有调用。
页面布局情况是这样的:视图A,有一个Pan手势;视图B是TabBarController,其ViewControllers都是NavigationController。视图B是视图A的子视图。
后来找到原因是:navigationController的interactive
pop手势与视图A的pan手势冲突。
具体原因是:rootViewController加载时,调用了didShowViewController:,设置interactivePopGestureRecognizer可用,其实我们并不需要在root的时候也触发这个手势。所以稍加优化如下:
// 优化
1 - (void)navigationController:(UINavigationController *)navigationController
2 didShowViewController:(UIViewController *)viewController
3 animated:(BOOL)animate
4 {
5 if ([navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
6 //if ([[navigationController.viewControllers firstObject] isEqual:viewController]) {
7 if ([navigationController.viewControllers count] == 1) {
8 // Disable the interactive pop gesture in the rootViewController of navigationController
9 navigationController.interactivePopGestureRecognizer.enabled = NO;
10 } else {
11 // Enable the interactive pop gesture
12 navigationController.interactivePopGestureRecognizer.enabled = YES;
13 }
14 }
15 }
当前显示的是root时,设置interactivePopGestureRecognizer不可用,非root时设置interactivePopGestureRecognizer可用。
参考文章:http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/
iOS 7 自定义Back按钮 与 Pop interactive gesture,码迷,mamicode.com