티스토리 뷰

개발하다 보면 뷰컨트롤러가 아닌 AppDelegate나 NSObject 클래스에서 UIAlertController를 띄우고 싶을때가 종종 있다.


UIAlertController를 사용할려면 뷰컨트롤러에서 present를 해야하고 최상위가 아닌 뷰컨트롤러에서 시도할 경우 아래와 같이 계층 에러가 발생한다.

(참고: viewDidLoad에서 바로 다른 뷰컨트롤러를 present를 하게 될 경우도 발생한다. 화면이 다 보여지지 않은 상태에서 다른 뷰컨트롤러를 보여준다는게 말이 안되기 때문이다.)


Warning: Attempt to present <UIViewController: 0x84ac3b0> on <ViewController: 0x81b0230> whose view is not in the window hierarchy!


그래서 아래와 같이 최상위 뷰컨트롤러를 구하는 클래스 함수를 만들어서 사용하고 있다.


class func topViewController() -> UIViewController? {

    if let keyWindow = UIApplication.shared.keyWindow {

        if var viewController = keyWindow.rootViewController {

            while viewController.presentedViewController != nil {

                viewController = viewController.presentedViewController!

            }

            print("topViewController -> \(String(describing: viewController))")

            return viewController

        }

    }

    return nil

}