美文网首页
swift 、OC 获取Controller或者View的方法

swift 、OC 获取Controller或者View的方法

作者: 762683ff5d3d | 来源:发表于2018-03-02 17:21 被阅读0次

    1、获取UIViewController

    场景1:

    在项目中,我们经常需要获取当前所看到的View Controller,比如从其他App跳回我们的App中时,获取当前View Controller:

      extension UIViewController {
        class func currentViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
            if let nav = base as? UINavigationController {
                return currentViewController(base: nav.visibleViewController)
            }
            
            if let tab = base as? UITabBarController {
                return currentViewController(base: tab.selectedViewController)
            }
            
            if let presented = base?.presentedViewController {
                return currentViewController(base: presented)
            }
            return base
        }
    }
    

    用法:

    let theViewControllerYouSee = UIViewController.currentViewController()
    

    场景2:如MVVM模式中使用

    当前view中获取UIViewController

    方法一: 通过响应者链获取
    // 获取view当前所在的UIViewController
        func getCurrentViewController() -> UIViewController {
            // 1.通过响应者链关系,取得此时图的下一个响应者
            var nextResp: UIResponder?
            nextResp = self.next!
            repeat {
                // 2.判断响应者对象是否是视图控制器类型
                if ((nextResp as? UIViewController) != nil) {
                    return nextResp as! UIViewController
                }
                else{
                    nextResp = next?.next
                }
            } while nextResp != nil
            
            return UIViewController()
        }
    

    上面的方法是根据下面的OC方法改写的

    - (UIViewController *) getCurrentViewController {
         UIResponder *next = [self nextResponder];
         do {
         if ([next isKindOfClass:[UIViewController class]]) {
         return (UIViewController *)next;
         }
         next = [next nextResponder];
         } while (next != nil);
         return nil;
         }
    
    方法二: 通过当前UIView的superView遍历获取
    1)UIView实例化调用
        func getCurrentViewController() -> UIViewController? {
            // 1.通过响应者链关系,取得此时图的下一个响应者
            var next: UIView? = self
            repeat {
                // 2.判断响应者对象是否是视图控制器类型
                if let nextResp = self.next , nextResp.isKind(of: UIViewController.self) {
                    return (nextResp as! UIViewController)
                }
                next = next?.superview
            } while next != nil
            
            return nil
        }
        
     2) UIView 静态调用
       static func currentViewController(view: UIView)-> UIViewController? {
            var next:UIView? = view
            repeat{
                if let nextResponder = next?.next,
    nextResponder.isKind(of: UIViewController.self) {
                    return (nextResponder as! UIViewController)
                }
                next = next?.superview
            }while next != nil
            return nil
        }
    
    注意:1)和 2)方法可在控制器中调用,但 方法一 和 1)方法 在自定义UIView中
    调用无反应,2)方法则可以,具体原因还有待研究,也希望知道的朋友告知。
    

    场景3:获取window中当前页面的最顶层控制器

    //获取当前页面的最顶层控制器
       func currentVc() -> UIViewController {
            let keywindow = UIApplication.shared.keyWindow
            let firstView: UIView = (keywindow?.subviews.first)!
            let secondView: UIView = firstView.subviews.first!
            let vc = viewForController(view: secondView)
            return vc!
        }
    
        func viewForController(view:UIView)->UIViewController?{
            var next:UIView? = view
            repeat{
                if let nextResponder = next?.next, nextResponder is UIViewController {
                    return (nextResponder as! UIViewController)
                }
                next = next?.superview
            }while next != nil
            return nil
        }
    
    调用方法:
    let vc = self.currentVc()//获取当前屏幕中顶层控制器
     if vc.childViewControllers.first is ManagerRootViewController {
             self.perform(#selector(ManagerRootViewController.disAction), on: Thread.main, with: nil, waitUntilDone: true)
        }
    //如果是UINavgitionController,那么其first就是rootViewController
    
    perform使用方法:
     在A控制器想让B控制器调用B中xx的方法,perform的用法
        onThread:执行xx方法的线程
        waitUntilDone:true代表先执行xx方法再执行一下代码.
    

    文章仅供参考,有不完善的地方,望朋友们相告知

    文章参考:

    https://www.jianshu.com/p/66ecd88b4210
    https://www.jianshu.com/p/30b341d5edfa

    相关文章

      网友评论

          本文标题:swift 、OC 获取Controller或者View的方法

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