[swift] 가장 많이 UIViewController 받기

UIViewController액세스하지 않으면 최고를 얻을 수없는 것 같습니다 UINavigationController. 여기 내가 지금까지 가지고있는 것입니다 :

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(vc, animated: true, completion: nil)

그러나 아무것도하지 않는 것 같습니다. keyWindowrootViewController옵션 체인은 문제가되지해야한다, 그래서 너무 nil이 아닌 값이 될 것으로 보인다.

참고 : 이와 같은 작업을 수행하는 것은 좋지 않습니다. MVC 패턴을 깨뜨립니다.



답변

presentViewController뷰 컨트롤러를 보여줍니다. 뷰 컨트롤러를 반환하지 않습니다. 를 사용하지 않는 경우 UINavigationController아마도 찾고 presentedViewController있을 것이고 루트에서 시작하여 제시 된보기를 반복해야합니다.

if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }

    // topController should now be your topmost view controller
}

스위프트 3 이상 :

if var topController = UIApplication.shared.keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }

    // topController should now be your topmost view controller
}

iOS 13 이상

let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first

if var topController = keyWindow?.rootViewController {
    while let presentedViewController = topController.presentedViewController {
        topController = presentedViewController
    }

// topController should now be your topmost view controller
}


답변

이 확장명을 가지고

스위프트 2. *

extension UIApplication {
    class func topViewController(controller: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? {
        if let navigationController = controller as? UINavigationController {
            return topViewController(navigationController.visibleViewController)
        }
        if let tabController = controller as? UITabBarController {
            if let selected = tabController.selectedViewController {
                return topViewController(selected)
            }
        }
        if let presented = controller?.presentedViewController {
            return topViewController(presented)
        }
        return controller
    }
}

스위프트 3

extension UIApplication {
    class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let navigationController = controller as? UINavigationController {
            return topViewController(controller: navigationController.visibleViewController)
        }
        if let tabController = controller as? UITabBarController {
            if let selected = tabController.selectedViewController {
                return topViewController(controller: selected)
            }
        }
        if let presented = controller?.presentedViewController {
            return topViewController(controller: presented)
        }
        return controller
    }
}

컨트롤러 어디에서나 사용할 수 있습니다

if let topController = UIApplication.topViewController() {

}


답변

Swift 4/5 +의 최상위 뷰를 얻으려면

// MARK: UIApplication extensions

extension UIApplication {

    class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {

        if let nav = base as? UINavigationController {
            return getTopViewController(base: nav.visibleViewController)

        } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
            return getTopViewController(base: selected)

        } else if let presented = base?.presentedViewController {
            return getTopViewController(base: presented)
        }
        return base
    }
}

사용하는 방법

if let topVC = UIApplication.getTopViewController() {
   topVC.view.addSubview(forgotPwdView)
}


답변

extension UIWindow {

    func visibleViewController() -> UIViewController? {
        if let rootViewController: UIViewController = self.rootViewController {
            return UIWindow.getVisibleViewControllerFrom(vc: rootViewController)
        }
        return nil
    }

    static func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {
        if let navigationController = vc as? UINavigationController,
            let visibleController = navigationController.visibleViewController  {
            return UIWindow.getVisibleViewControllerFrom( vc: visibleController )
        } else if let tabBarController = vc as? UITabBarController,
            let selectedTabController = tabBarController.selectedViewController {
            return UIWindow.getVisibleViewControllerFrom(vc: selectedTabController )
        } else {
            if let presentedViewController = vc.presentedViewController {
                return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController)
            } else {
                return vc
            }
        }
    }
}

용법:

if let topController = window.visibleViewController() {
    println(topController)
}


답변

Objective-C 버전 인 Dianz 답변을 기반으로 함

- (UIViewController *) topViewController {
   UIViewController *baseVC = UIApplication.sharedApplication.keyWindow.rootViewController;
   if ([baseVC isKindOfClass:[UINavigationController class]]) {
       return ((UINavigationController *)baseVC).visibleViewController;
   }

   if ([baseVC isKindOfClass:[UITabBarController class]]) {
       UIViewController *selectedTVC = ((UITabBarController*)baseVC).selectedViewController;
       if (selectedTVC) {
           return selectedTVC;
       }
   }

   if (baseVC.presentedViewController) {
       return baseVC.presentedViewController;
   }
   return baseVC;
}


답변

나는 @ dianz ‘s answer을 좋아했으며 여기에 신속한 3 버전이 있습니다. 기본적으로는 동일하지만 중괄호가 누락되어 구문 / 변수 / 방법 이름 중 일부가 변경되었습니다. 그래서 여기 있습니다!

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

사용법은 여전히 ​​똑같습니다.

if let topController = UIApplication.topViewController() {
    print("The view controller you're looking at is: \(topController)")
}


답변

https://gist.github.com/db0company/369bfa43cb84b145dfd8
이 사이트의 답변과 의견에 대해 몇 가지 테스트를 수행했습니다. 나를 위해 다음과 같은 작품

extension UIViewController {
    func topMostViewController() -> UIViewController {

        if let presented = self.presentedViewController {
            return presented.topMostViewController()
        }

        if let navigation = self as? UINavigationController {
            return navigation.visibleViewController?.topMostViewController() ?? navigation
        }

        if let tab = self as? UITabBarController {
            return tab.selectedViewController?.topMostViewController() ?? tab
    }

        return self
    }
}

extension UIApplication {
    func topMostViewController() -> UIViewController? {
        return self.keyWindow?.rootViewController?.topMostViewController()
    }
}

그런 다음 상단 뷰 컨트롤러를 가져옵니다.

UIApplication.shared.topMostViewController()