前因
人活一輩子,總要遇上一些事情。
拿我自己來(lái)說(shuō)
便是實(shí)現(xiàn)iOS全屏右滑返回。
我開始參考的是啊崢的文章
【8行代碼教你搞定導(dǎo)航控制器全屏滑動(dòng)返回效果】
實(shí)現(xiàn)起來(lái)卻是遇上了不少問題,因?yàn)槭謩?shì)代理方法做的判斷不夠完善,還有好幾個(gè)情況下觸發(fā)手勢(shì)導(dǎo)致bug出現(xiàn)。
總的來(lái)說(shuō)有三種情況下手勢(shì)不應(yīng)該執(zhí)行:
- 當(dāng)前controller是rootViewController時(shí)
- pop動(dòng)畫正在進(jìn)行時(shí)
- 左滑時(shí)
另外。
該文采取的辦法是對(duì)navigationController自帶的interactivePopGestureRecognizer下手,禁用interactivePopGestureRecognizer,給interactivePopGestureRecognizer的delegate換上自定義的UIPanGestureRecognizer。
是否有更簡(jiǎn)單的辦法?有的。
// 更換interactivePopGestureRecognizer的delegate
// 這里設(shè)置為navigationController自己
self.interactivePopGestureRecognizer.delegate = self;
// 自帶的邊緣返回手勢(shì)的類是UIScreenEdgePanGestureRecognizer,只負(fù)責(zé)edge部分
// 那么換成包容心更強(qiáng)的UIPanGestureRecognizer
object_setClass(self.interactivePopGestureRecognizer, [UIPanGestureRecognizer class]);
可是還是喜歡拿來(lái)主義。
于是在github上找到:
sunnyxxx的FDFullscreenPopGesture
sunnyxxx已經(jīng)封裝得很完美了,完全AOP。在其手勢(shì)代理方法中,除了上面提到的三種情況,還增加了兩種情況,通過(guò)設(shè)置controller的兩個(gè)屬性控制手勢(shì)。
- fd_interactivePopDisabled:可單獨(dú)關(guān)閉某個(gè)controller的滑動(dòng)返回手勢(shì)
- fd_interactivePopMaxAllowedInitialDistanceToLeftEdge:自定義手勢(shì)范圍。
拿來(lái)主義真好。
我把代碼改了下,對(duì)delegate下手,代碼如下。
// if (![self.interactivePopGestureRecognizer.view.gestureRecognizers containsObject:self.fd_fullscreenPopGestureRecognizer]) {
//
// // Add our own gesture recognizer to where the onboard screen edge pan gesture recognizer is attached to.
// [self.interactivePopGestureRecognizer.view addGestureRecognizer:self.fd_fullscreenPopGestureRecognizer];
//
// // Forward the gesture events to the private handler of the onboard gesture recognizer.
// NSArray *internalTargets = [self.interactivePopGestureRecognizer valueForKey:@"targets"];
// id internalTarget = [internalTargets.firstObject valueForKey:@"target"];
// SEL internalAction = NSSelectorFromString(@"handleNavigationTransition:");
// self.fd_fullscreenPopGestureRecognizer.delegate = self.fd_popGestureRecognizerDelegate;
// [self.fd_fullscreenPopGestureRecognizer addTarget:internalTarget action:internalAction];
//
// // Disable the onboard gesture recognizer.
// self.interactivePopGestureRecognizer.enabled = NO;
// }
if ([self.interactivePopGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
object_setClass(self.interactivePopGestureRecognizer, [UIPanGestureRecognizer class]);
self.interactivePopGestureRecognizer.delegate = self.fd_popGestureRecognizerDelegate;
}
后果
再也不需要自定義手勢(shì)+截圖實(shí)現(xiàn)返回轉(zhuǎn)場(chǎng)那種老方法了。