Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持 setViewControllers:animate: 方法 #103

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<UIViewController *> *)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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down