一穷当、手勢(shì)右滑返回效果失效
在我們經(jīng)常使用的APP中,已經(jīng)習(xí)慣右滑返回這個(gè)效果,可是我發(fā)現(xiàn)我們的APP中這個(gè)功能失效了情萤,只能點(diǎn)擊左上角的返回按鈕才能執(zhí)行返回這個(gè)效果。后來(lái)查了一下發(fā)現(xiàn)摹恨,導(dǎo)致這個(gè)問(wèn)題的原因是因?yàn)槲覀冏约鹤远x了左上角的leftBarButtonItem筋岛,我們自定義了這個(gè)BarButtonItem使得系統(tǒng)不能捕獲pop手勢(shì)了。
解決方法:
創(chuàng)建一個(gè)UINavigationController的子類LGJBaseNavController晒哄,該類@interface LGJBaseNavController ()睁宰,所有的關(guān)于導(dǎo)航控制器的操作都在這個(gè)類里面操作。
1 設(shè)置手勢(shì)的delegate為self寝凌,導(dǎo)航控制器的delegate也為self柒傻。
- (void)viewDidLoad {
[super viewDidLoad];
__weak LGJBaseNavController *weakSelf = self;
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
return [super popViewControllerAnimated:animated];
}
2 在轉(zhuǎn)場(chǎng)/過(guò)渡的時(shí)候禁用 interactivePopGestureRecognizer當(dāng)用戶在轉(zhuǎn)場(chǎng)的時(shí)候觸發(fā)一個(gè)后退手勢(shì),這時(shí)候容易各種其他事件也會(huì)被喚醒较木,導(dǎo)航椇旆或邊混亂。那么在轉(zhuǎn)場(chǎng)效果的過(guò)程中禁用手勢(shì)識(shí)別,當(dāng)新的視圖控制器加載完成后再啟用。
#pragma mark - UINavigationControllerDelegate
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.interactivePopGestureRecognizer.enabled = NO;
}
//設(shè)置返回按鈕
if (self.viewControllers.count > 0) {
viewController.navigationItem.leftBarButtonItem = [self backButtonItem];
}
[super pushViewController:viewController animated:animated];
}
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.interactivePopGestureRecognizer.enabled = YES;
}
}
3 使navigationcontroller中第一個(gè)控制器不響應(yīng)右滑pop手勢(shì)
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self.childViewControllers count] == 1) {
return NO;
}
return YES;
}
4 解決多個(gè)手勢(shì)沖突 同時(shí)接受多個(gè)手勢(shì)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
5 解決在手指滑動(dòng)時(shí)候,被pop的viewController中的UIscrollView會(huì)跟著一起滾動(dòng)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];
}
關(guān)于這個(gè)處理復(fù)雜手勢(shì)沖突的方法有幾個(gè)類似的手勢(shì)代理方法:
//手指觸摸屏幕后回調(diào)的方法预侯,返回NO則不再進(jìn)行手勢(shì)識(shí)別致开,方法觸發(fā)等
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
//開(kāi)始進(jìn)行手勢(shì)識(shí)別時(shí)調(diào)用的方法,返回NO則結(jié)束雌桑,不再觸發(fā)手勢(shì)
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
//是否支持多時(shí)候觸發(fā)喇喉,返回YES,則可以多個(gè)手勢(shì)一起觸發(fā)方法校坑,返回NO則為互斥
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
//下面這個(gè)兩個(gè)方法也是用來(lái)控制手勢(shì)的互斥執(zhí)行的
//這個(gè)方法返回YES拣技,第一個(gè)手勢(shì)和第二個(gè)互斥時(shí),第一個(gè)會(huì)失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
//這個(gè)方法返回YES耍目,第一個(gè)和第二個(gè)互斥時(shí)膏斤,第二個(gè)會(huì)失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
可以將這幾個(gè)方法寫(xiě)在一個(gè)UINavigationController的子類里面,然后在AppDelegate中設(shè)置self.window.rootViewController = [[LGJBaseNavController alloc] initWithRootViewController:vc1];可以處理全局的導(dǎo)航控制器關(guān)于這個(gè)右滑手勢(shì)返回失效的問(wèn)題邪驮,我以上寫(xiě)的這些方法直接寫(xiě)在里面就可以莫辨。另外說(shuō)一句,在這個(gè)LGJBaseNavController中可以設(shè)置導(dǎo)航欄的一些自定義樣式:比如這種樣式就可以在LGJBaseNavController初始化中設(shè)置:
navBar.png
+ (void)initialize {
//bar樣式
UINavigationBar *bar = [UINavigationBar appearance];
[bar setBarStyle:UIBarStyleDefault];
[bar setBarTintColor:[UIColor blackColor]];
[bar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor],NSForegroundColorAttributeName, nil]];
//barButton樣式
UIBarButtonItem *item = [UIBarButtonItem appearance];
//Normal
NSMutableDictionary *textAtts = [NSMutableDictionary dictionary];
textAtts[NSForegroundColorAttributeName] = [UIColor orangeColor];
textAtts[NSFontAttributeName] = [UIFont systemFontOfSize:13];
[item setTitleTextAttributes:textAtts forState:UIControlStateNormal];
//不可用狀態(tài)
NSMutableDictionary *disableTextAtts = [NSMutableDictionary dictionary];
disableTextAtts[NSForegroundColorAttributeName] = [UIColor colorWithRed:123/255.0 green:123/255.0 blue:123/255.0 alpha:1];
disableTextAtts[NSFontAttributeName] = [UIFont systemFontOfSize:13];
[item setTitleTextAttributes:disableTextAtts forState:UIControlStateDisabled];
}
二毅访、隱藏NavigationBar返回時(shí)沮榜,上面會(huì)有空缺
這個(gè)應(yīng)該也是我們經(jīng)常見(jiàn)的效果,比如vc1跳轉(zhuǎn)vc2喻粹,vc2的導(dǎo)航欄是隱藏的蟆融,當(dāng)從vc2返回vc1時(shí),在這個(gè)過(guò)程中守呜,放慢看上面會(huì)有缺失一塊型酥,放快了看就是閃屏,這個(gè)效果對(duì)用戶也是不友好的查乒,這個(gè)解決方法比較簡(jiǎn)單弥喉。就是在次級(jí)viewControleller中在設(shè)置setNavigationBarHidden時(shí)這樣設(shè)置: <重要的是后面的animated參數(shù)>
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
注:此文章為轉(zhuǎn)載,原文地址:http://www.cocoachina.com/ios/20170602/19418.html