web-dev-qa-db-ja.com

AppDelegateでSwiftにアラートを表示

私は次のコードスニペットを試します:

var alert = UIAlertController(title: "Alert", message: "Cannot connect to : \(error!.localizedDescription)", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)

私のAppDelegateでは、コンソールに次のエラーが表示されます:

Warning: Attempt to present <UIAlertController: 0x7ff6cd827a30> on <Messenger.WelcomeController: 0x7ff6cb51c940> whose view is not in the window hierarchy!

このエラーを修正するにはどうすればよいですか?

24
Orkhan Alizade

これは私が今それを行うために使用しているものです。

var alertController = UIAlertController(title: "Title", message: "Any message", preferredStyle: .ActionSheet)
var okAction = UIAlertAction(title: "Yes", style: UIAlertActionStyle.Default) {
                    UIAlertAction in
                    NSLog("OK Pressed")
                }
var cancelAction = UIAlertAction(title: "No", style: UIAlertActionStyle.Cancel) {
                    UIAlertAction in
                    NSLog("Cancel Pressed")
                }
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.window?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
30

スイフト3

let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertControllerStyle.alert)

// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

// show the alert
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
16
Ahmed Safadi

Swift 3.0以降、タブバーの場合、表示されたビューの場合など、すべての条件で動作します。

let alert = UIAlertController(title: "Test", message:"Message", preferredStyle: UIAlertControllerStyle.alert)

// add an action (button)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))

// show alert
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1;
alertWindow.makeKeyAndVisible()
alertWindow.rootViewController?.present(alertController, animated: true, completion: nil)
13
emraz

Jorgeの回答に従って、Swift 4

let alertController = UIAlertController(title: "Title", message: "Message", preferredStyle: .actionSheet)
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
        UIAlertAction in
        NSLog("OK Pressed")
    }
let cancelAction = UIAlertAction(title: "CANCEL", style: UIAlertActionStyle.cancel) {
        UIAlertAction in
        NSLog("Cancel Pressed")
    }
alertController.addAction(okAction)
alertController.addAction(cancelAction)
self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
11
Chris Herbst

同様の問題がありました。

Main QueueUIAlertControllerを表示することで修正しました。

コードは次のようになります。

let alert = UIAlertController(title: "My Title", message: "My Message", preferredStyle: .alert)

let actionYes = UIAlertAction(title: "Yes", style: .default, handler: { action in
print("action yes handler")
})

let actionCancel = UIAlertAction(title: "Cancel", style: .destructive, handler: { action in
print("action cancel handler")
})

alert.addAction(actionYes)
alert.addAction(actionCancel)

DispatchQueue.main.async {
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
7

ApplicationDidFinishLunchingWithOptions:からそのコードスニペットを呼び出していると思います。私がしなければならなかったので、私は実際問題としてそれを試しました。問題は、あなたがやろうとしていることは正しいことですが、AppDelegateが作成して提示するViewControllerを画面に表示しようとしています。その前に、コードスニペットはalertViewを作成し、存在しないView RootViewController。

私がすることは、RootViewControllerが提示された後に呼び出されることが保証されている別のデリゲート呼び出しにそれを移動することです。

    func applicationDidBecomeActive(application: UIApplication) {
     //This method is called when the rootViewController is set and the view.
     // And the View controller is ready to get touches or events.
    var alert = UIAlertController(title: "Alert", message: "Cannot connect to :", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
    self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)

    }

しかし、いつものようにAppDelegateの責任を知っています。これは、アプリケーションのライフサイクルとアプリケーション全体のデリゲート呼び出しとイベントを処理することです。ここにコードを置くことが理にかなっているなら、それをしてください。しかし、rootViewControllerまたは他の部分にコードを配置した方が良い場合は、それについても考えてください。

とにかく、それが役立つことを願っています。乾杯!

3
kandelvijaya

UIApplication.shared.keyWindow?.rootViewController?.present(...)を使用してみましたか?

3
Mijax

AppDelegateではこれを行わないことをお勧めします。 App Delegateは、アラートビューなどを実装するのではなく、OSからのDelegate機能を処理することを目的としていました。

アプリの開始時に表示されるアラートビューをここに表示する場合は、最初のビューコントローラーに実装することでこれを行います。

0
Swinny89