LoginSignup
13
5

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-05-02

環境

  • macOS HighSierra 10.13.4
  • Xcode 9.3
  • Swift 4.1

事象

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

ViewController.swift

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がない状態でアラートを表示(追加)することができないということであった。

[参考記事]
- iOS のイベント駆動をライフサイクルイベントとユーザアクションイベントにわけて理解する
- UIViewControllerのライフサイクル

対処方法

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

ViewController.swift

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

// View構築後の処理
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // アラート表示
    self.showAlert("Alert Message!!")
}

// アラート表示の処理
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)
}

まとめ

  • iOSライフサイクルの重要性
13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5