項(xiàng)目里有需求要自定義返回按鈕阔籽,在攔截全局push方法之后流妻,發(fā)現(xiàn)系統(tǒng)自帶的返回手勢(shì)不能用了。
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.childViewControllers.count > 0) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];
[btn setTitle:@"返回" forState:UIControlStateNormal];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
btn.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0);
[btn sizeToFit];
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
}
[super pushViewController:viewController animated:animated];
}
思路:
考慮到返回手勢(shì)和手勢(shì)有關(guān)笆制,進(jìn)入U(xiǎn)INavigationController頭文件绅这,搜索UIGestureRecognizer
找到屬性:interactivePopGestureRecognizer
這時(shí)候猜測(cè)一下,手勢(shì)失效的原因在辆。1.為空值证薇,2修改了代理方法。
self.interactivePopGestureRecognizer.delegate = nil;
將屬性置空匆篓,確實(shí)解決問(wèn)題浑度,但是回到根目錄左滑,會(huì)導(dǎo)致屏幕卡死鸦概,不能點(diǎn)擊箩张。
最后修改代理方法,代碼如下:
//
// LPNavigationController.m
// BSBDJ
//
// Created by 劉鵬 on 2019/10/12.
// Copyright ? 2019 劉鵬. All rights reserved.
//
#import "LPNavigationController.h"
@interface LPNavigationController ()<UIGestureRecognizerDelegate>
@end
@implementation LPNavigationController
+ (void)load {
NSMutableDictionary *attDic = [NSMutableDictionary dictionary];
attDic[NSFontAttributeName] = [UIFont systemFontOfSize:20];
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[self class]]] setTitleTextAttributes:attDic];
[[UINavigationBar appearanceWhenContainedInInstancesOfClasses:@[[self class]]] setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.interactivePopGestureRecognizer.delegate = self;
}
- (void)back {
[self popViewControllerAnimated:YES];
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (self.childViewControllers.count > 0) {
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemwithImage:@"navigationButtonReturn" highImage:@"navigationButtonReturnClick" title:@"返回" target:self action:@selector(back)];
}
[super pushViewController:viewController animated:animated];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return self.childViewControllers.count > 1;
}
@end
這時(shí)候只是保持了系統(tǒng)原有的滑動(dòng)返回功能窗市,只能從屏幕的最左側(cè)向右邊滑動(dòng)先慷。如果想在屏幕的其他地方,從左往右滑動(dòng)谨设,就需要繼續(xù)來(lái)研究熟掂。
我們打印一下NSLog(@"%@", self.interactivePopGestureRecognizer.delegate);
得到:<_UINavigationInteractiveTransition: 0x7fe05b802650>
打印NSLog(@"%@", self.interactivePopGestureRecognizer);
得到:<UIScreenEdgePanGestureRecognizer: 0x7fd192510f30; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7fd195d03f50>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fd192510760>)>>
這個(gè)UIScreenEdgePanGestureRecognizer的父類是UIPanGestureRecognizer。
這個(gè)時(shí)候我們要重新給控制器的view添加一個(gè)滑動(dòng)方法:
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:<#(nullable id)#> action:<#(nullable SEL)#>];
上面打印的這行(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7fd192510760>)扎拣,就是系統(tǒng)內(nèi)部調(diào)用的赴肚,我們可以直接拿來(lái)用。
- (void)viewDidLoad {
[super viewDidLoad];
// self.interactivePopGestureRecognizer.delegate = self;
// NSLog(@"%@", self.interactivePopGestureRecognizer.delegate);
// <_UINavigationInteractiveTransition: 0x7f99f9d0cb10>
// NSLog(@"%@", self.interactivePopGestureRecognizer);
// <UIScreenEdgePanGestureRecognizer: 0x7faab4c103c0; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7faab4c0dc80>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7faab4c10280>)>>
// 自己定義全屏滑動(dòng)
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
[self.view addGestureRecognizer:pan];
// 用來(lái)配合代理方法二蓝,根控制器不能滑動(dòng)誉券,push的可以滑動(dòng)
pan.delegate = self;
// 自己定義了返回手勢(shì),把系統(tǒng)的停用
self.interactivePopGestureRecognizer.enabled = NO;
}