美文网首页
iOS开发——使用导航控制器时,如何优雅的回到指定的界面

iOS开发——使用导航控制器时,如何优雅的回到指定的界面

作者: 青苹果园 | 来源:发表于2017-11-28 10:47 被阅读57次

    在开发中我们很多地方都会用到UINavigationController去管理我们子控制器,这就涉及到界面的跳转问题,特别是需要跳转到指定界面的时候,有时直接使用苹果api并不能完全达到我们想要的效果。

    例如:当我做一个购买套餐的模块的时候,选择套餐界面定位界面一,选择支付方式为界面二,展示支付成功状态为界面三,我希望在界面三点击返回直接回到界面一,这时使用苹果的回到指定的子控制器的api,popToViewController: animated:会有一个界面切换的过程,这并不是我想要的效果,我希望直接返回到界面一。

    解决方案:根据UINavigationController以栈的形式来保存子控制器的特性,在界面三显示完成后即viewDidAppear:中把界面二从栈中移除即可,然后正常调用pop方法即可。

    首先简单的介绍下UINavigationController的一些常用属性。

    我们都知道UINavigationController是以栈的形式来保存子控制器,用viewControllers和childViewControllers来表示。

    @property(nonatomic,copy) NSArray *viewControllers;
    @property(nonatomic,readonly) NSArray *childViewControllers;
    

    使用push方法能将某个控制器压入栈:

    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;
    

    使用pop方法可以移除控制器:

    // 移除当前控制器
    - (UIViewController *)popViewControllerAnimated:(BOOL)animated;
     
    // 回到指定的子控制器 
    - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;
     
     // 和回到根控制器(栈底控制器)
    - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;
    

    如何修改导航栏的内容:

    导航栏的内容由栈顶控制器的navigationItem属性决定

    // 左上角的返回按钮
    @property(nonatomic,retain) UIBarButtonItem *backBarButtonItem;
    
    // 中间的标题视图
    @property(nonatomic,retain) UIView          *titleView;
    
    // 中间的标题文字
    @property(nonatomic,copy)   NSString        *title;
    
    // 左上角的视图
    @property(nonatomic,retain) UIBarButtonItem *leftBarButtonItem;
    
    // UIBarButtonItem *rightBarButtonItem  右上角的视图
    @property(nonatomic,retain) UIBarButtonItem *rightBarButtonItem;
    

    优雅的回到指定的界面

    OC

    先从导航栏控制器的栈中,移除指定的子控制器,然后调用pop方法。

    // 这里的ZDIntegralTableViewController为指定需要移除的控制器
      NSMutableArray *viewControllers = [self.navigationController.viewControllers mutableCopy];
      for (UIViewController *VC in viewControllers) {
         if ([VC isKindOfClass:[ZDIntegralTableViewController class]]) {
            [viewControllers removeObject:VC];
            break;
         }
      }
      self.navigationController.viewControllers = [viewControllers copy];
    

    Swift

    func backButtonAction() {
            guard let VCs = self.navigationController?.childViewControllers else {
                super.backButtonAction()
                return
            }
            var holdingFundDetailVC: HoldingFundDetailViewController?
            for VC in VCs where VC is HoldingFundDetailViewController {
                holdingFundDetailVC = VC as? HoldingFundDetailViewController
                break
            }
            if let detailVC = holdingFundDetailVC {
                self.navigationController?.popToViewController(detailVC, animated: true)
            } else {
                super.backButtonAction()
            }
    }
    

    跳转至目标页,同时移除之前的过程控制器

        /// 跳转至目标页,同时移除之前的过程控制器
        ///
        /// - Parameters:
        ///   - targetController: 目标页
        ///   - designedController: 需要移除的控制器
        func pushTargetControllerAndRemoveDesignedController(targetController: UIViewController, designedController: UIViewController) {
            let nav = self.navigationController
            let index: Int = nav?.viewControllers.index(of: designedController) ?? 0
            var viewControllers = [UIViewController]()
            if let originVCs = nav?.viewControllers[0..<index] {
                viewControllers = Array(originVCs)
            }
            targetController.hidesBottomBarWhenPushed = true
            viewControllers.append(targetController)
            nav?.setViewControllers(viewControllers, animated: true)
        }
    

    相关文章

      网友评论

          本文标题: iOS开发——使用导航控制器时,如何优雅的回到指定的界面

          本文链接:https://www.haomeiwen.com/subject/oqesbxtx.html