元柔道整復師エンジニアBlog

- 元柔道整復師エンジニアBlog -

『 エンジニアをリングする。』

【Swift】シュミレータ起動時に「Attempt to present <*> on <*> whose view is not in the window hierarchy!」が発生したときの対処方法

環境

事象

ViewContorollerのviewDidLoadメソッド内において、アラート表示させる処理を以下のように追加し、

override func viewDidLoad() {
    super.viewDidLoad()
    
    // アラート表示
    self.showAlert("Message Alert!!")
}

// アラート表示の処理
func showAlert(_ alertMessage: String) {
    let alertConroller = UIAlertController(
        title: "Alert", message: alertMessage, preferredStyle: .alert)
    let originAction = UIAlertAction(
        title: "OK", style: .default, handler: nil)
    alertConroller.addAction(originAction)
    self.present(alertConroller, animated: true, completion: nil)
}

シュミレータを起動するとコンソール上に、 「アラートを表示しようとしたが、Viewがないため追加できない」というがエラー出る。

2018-05-02 21:44:12.082835+0900 ***App[88818:8813297] Warning: Attempt to present <UIAlertController: 0x7f929b88a600> on <***App.ViewController: 0x7f929b6114a0> whose view is not in the window hierarchy!

原因

iOSのライフサイクルに反していることによるもの。

アラートは本来、Viewを構築ViewDidLoad()したあとに追加しなければいけないため、 エラー内容通り、Viewがない状態でアラートを表示(追加)することができないということであった。

[参考記事]

対処

アラート表示の処理は、Viewが構築された(画面描画が終わった)あとに追加する必要があるため、 Viewの読み込み終了時に呼ばれるViewDidLoad()内ではなく、画面描画の終了時に呼ばれるviewDidAppear()というメソッドが用意されているのでそこに処理を追加する。

// View構築
override func viewDidLoad() {
    super.viewDidLoad()
}

// View構築後の処理
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    
    // アラート表示
    self.showAlert("Message Alert!!")
}

// アラート表示の処理
func showAlert(_ alertMessage: String) {
    let alertConroller = UIAlertController(
        title: "Alert", message: alertMessage, preferredStyle: .alert)
    let originAction = UIAlertAction(
        title: "OK", style: .default, handler: nil)
    alertConroller.addAction(originAction)
    self.present(alertConroller, animated: true, completion: nil)
}