使用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];
}

上一篇下一篇

猜你喜欢

热点阅读