From 7bd276f0d119561597e544119508f8ed6bf06d1e Mon Sep 17 00:00:00 2001 From: YanWei Date: Thu, 20 Oct 2016 20:51:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=20setViewControllers:animate?= =?UTF-8?q?:=20=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...igationController+FDFullscreenPopGesture.m | 62 +++++++++++++++---- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m b/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m index 914f217..b46cd13 100644 --- a/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m +++ b/FDFullscreenPopGesture/UINavigationController+FDFullscreenPopGesture.m @@ -50,7 +50,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer if (maxAllowedInitialDistance > 0 && beginningLocation.x > maxAllowedInitialDistance) { return NO; } - + // Ignore pan gesture when the navigation controller is currently in transition. if ([[self.navigationController valueForKey:@"_isTransitioning"] boolValue]) { return NO; @@ -142,33 +142,69 @@ + (void)load method_exchangeImplementations(originalMethod, swizzledMethod); } }); + + // Inject "-setViewControllers:animated:" + static dispatch_once_t onceToken2; + dispatch_once(&onceToken2, ^{ + Class class = [self class]; + + SEL originalSelector = @selector(setViewControllers:animated:); + SEL swizzledSelector = @selector(fd_setViewControllers:animated:); + + Method originalMethod = class_getInstanceMethod(class, originalSelector); + Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); + + BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); + if (success) { + class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, swizzledMethod); + } + }); } - (void)fd_pushViewController:(UIViewController *)viewController animated:(BOOL)animated +{ + [self fd_addFullscreenPopGestureRecognizer]; + + // Handle perferred navigation bar appearance. + [self fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController]; + + // Forward to primary implementation. + if (![self.viewControllers containsObject:viewController]) { + [self fd_pushViewController:viewController animated:animated]; + } +} + +- (void)fd_setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated +{ + [self fd_addFullscreenPopGestureRecognizer]; + + // Handle perferred navigation bar appearance. + for (UIViewController *viewController in viewControllers) { + [self fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController]; + } + + [self fd_setViewControllers:viewControllers animated:animated]; +} + +- (void)fd_addFullscreenPopGestureRecognizer { 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; } - - // Handle perferred navigation bar appearance. - [self fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController]; - - // Forward to primary implementation. - if (![self.viewControllers containsObject:viewController]) { - [self fd_pushViewController:viewController animated:animated]; - } } - (void)fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:(UIViewController *)appearingViewController @@ -198,7 +234,7 @@ - (void)fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:(UIViewContro - (_FDFullscreenPopGestureRecognizerDelegate *)fd_popGestureRecognizerDelegate { _FDFullscreenPopGestureRecognizerDelegate *delegate = objc_getAssociatedObject(self, _cmd); - + if (!delegate) { delegate = [[_FDFullscreenPopGestureRecognizerDelegate alloc] init]; delegate.navigationController = self; @@ -211,7 +247,7 @@ - (_FDFullscreenPopGestureRecognizerDelegate *)fd_popGestureRecognizerDelegate - (UIPanGestureRecognizer *)fd_fullscreenPopGestureRecognizer { UIPanGestureRecognizer *panGestureRecognizer = objc_getAssociatedObject(self, _cmd); - + if (!panGestureRecognizer) { panGestureRecognizer = [[UIPanGestureRecognizer alloc] init]; panGestureRecognizer.maximumNumberOfTouches = 1;