使用setViewControllers:animated:的方
2019-07-27 本文已影响0人
独孤流
前言
开发中遇到一个需求,在某些页面点击注册按钮弹出注册页面,在点击注册成功后自动
pop
动画回退到之前没展示过的登录页面,也就是说UINavigationController同时push多个controller到栈里,而平常使用的pushViewController:animated:
只能push一个controller到栈里
解决方法:
在查了下API后发现一家有一个系统方法实现了这个功能
- (void)setViewControllers:(NSArray<UIViewController *> *)viewControllers animated:(BOOL)animated NS_AVAILABLE_IOS(3_0); // If animated is YES, then simulate a push or pop depending on whether the new top view controller was previously in the stack.
setViewControllers:animated:
关于我的这个业务的具体例子如下:
- (void)showRegister
{
// 登录页面
LoginViewController *login = [[LoginViewController alloc]init];
// 注册页面
RegisterViewController *registerVC = [[RegisterViewController alloc] init];
// 放一个空白VC占位,否则有各自奇怪的问题
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:[UIViewController new]];
// 一次放多个Controller到栈里
[nav setViewControllers:@[login,registerVC] animated:NO];
UIViewController *rootVC = [UIApplication sharedApplication].delegate.window.rootViewController;
// 使用model的方式展示注册页面
[rootVC presentViewController: nav animated: YES completion:nil];
}
问题二:
由于这个业务设置了再注册页面是不能有侧滑返回功能,点击返回按钮也会有提示,而因为侧滑功能使用的是FDFullscreenPopGesture这个框架统一处理,但是这个空间没有处理
setViewControllers:animated:
这种情况,许愿 修改框架源码,修改如下:在处理-pushViewController:animated:
的地方依葫芦画瓢添加对setViewControllers:animated:
的支持
+ (void)load
{
// Inject "-pushViewController:animated:"
Method originalMethod = class_getInstanceMethod(self, @selector(pushViewController:animated:));
Method swizzledMethod = class_getInstanceMethod(self, @selector(fd_pushViewController:animated:));
method_exchangeImplementations(originalMethod, swizzledMethod);
Method originalMethod2 = class_getInstanceMethod(self, @selector(setViewControllers:animated:));
Method swizzledMethod2 = class_getInstanceMethod(self, @selector(fd_setViewControllers:animated:));
method_exchangeImplementations(originalMethod2, swizzledMethod2);
}
- (void)fd_setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
{
for(UIViewController *viewController in viewControllers){
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;
}
[self fd_setupViewControllerBasedNavigationBarAppearanceIfNeeded:viewController];
}
[self fd_setViewControllers:viewControllers animated:animated];
}