web-dev-qa-db-ja.com

ViewControllerの外部にUIAlertControllerを表示する

ViewControllerではないクラスで表示しようとしているため、UIAlertControllerを表示するのに問題があります。

私はすでにそれを追加しようとしました:

 var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)

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

これは機能していません...私はまだ私のために機能する解決策を見つけられませんでした。

15
Michael

show()を取り戻すために、このextensionUIAlertControllerの上に書きました。
再帰を使用して、現在のトップビューコントローラーを検索します。

extension UIAlertController {

    func show() {
        present(animated: true, completion: nil)
    }

    func present(#animated: Bool, completion: (() -> Void)?) {
        if let rootVC = UIApplication.sharedApplication().keyWindow?.rootViewController {
            presentFromController(rootVC, animated: animated, completion: completion)
        }
    }

    private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) {
        if let navVC = controller as? UINavigationController,
            let visibleVC = navVC.visibleViewController {
                presentFromController(visibleVC, animated: animated, completion: completion)
        } else
        if let tabVC = controller as? UITabBarController,
            let selectedVC = tabVC.selectedViewController {
                presentFromController(selectedVC, animated: animated, completion: completion)
        } else {
            controller.presentViewController(self, animated: animated, completion: completion);
        }
    }
}

今では次のように簡単です。

var alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)
alertController.show()

編集:

Xcode 8.0の場合&Swift 3:

extension UIAlertController {

    func show() {
        present(animated: true, completion: nil)
    }

    func present(animated: Bool, completion: (() -> Void)?) {
        if let rootVC = UIApplication.shared.keyWindow?.rootViewController {
            presentFromController(controller: rootVC, animated: animated, completion: completion)
        }
    }

    private func presentFromController(controller: UIViewController, animated: Bool, completion: (() -> Void)?) {
        if let navVC = controller as? UINavigationController,
            let visibleVC = navVC.visibleViewController {
            presentFromController(controller: visibleVC, animated: animated, completion: completion)
        } else
            if let tabVC = controller as? UITabBarController,
                let selectedVC = tabVC.selectedViewController {
                presentFromController(controller: selectedVC, animated: animated, completion: completion)
            } else {
                controller.present(self, animated: animated, completion: completion);
        }
    }
}
31
Aviel Gross

現在のViewControllerから呼び出すヘルパー関数を作成し、現在のViewControllerをパラメーターとして渡します。

func showAlertInVC(
  viewController: UIViewController, 
  title: String, 
message: String)
{
  //Code to create an alert controller and display it in viewController
}
1
Duncan C

これはうまくいくはずです。

 UIApplication.sharedApplication().windows[0].rootViewController?.presentViewController(...)
1
Steve Glick

ソリューションが機能しない場合は、おそらくその時点でウィンドウがないためです。 application:DidFinishLoadingWithOptionsメソッドでアラートビューを表示しようとしたときに同じ問題が発生しました。この場合、私の解決策は、ルートビューコントローラーが使用可能かどうかを確認し、使用できない場合は、UIApplicationDidBecomeActiveNotificationの通知を追加することでした。

NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationDidBecomeActiveNotification,
                object: nil,
                queue: NSOperationQueue.mainQueue()) {
                    (_) in
                        //show your alert by using root view controller
                        //remove self from observing
                    }
        }
0
Vasyl Khmil