2015年9月4日金曜日

AlertControllerの書き方


SwiftでAlertを表示しようと思い、AlertControllerのコードを書いたのだが、表示されない。

ログには

whose view is not in the window hierarchy!

などというエラーメッセージが表示されている。

調べたら、viewDidLoad()中に書いていたせいで、viewDidAppear()中に書きなおしたら表示できた
viewDidLoad()の段階ではviewの情報が読み込まれただけだから、画面上の部品の階層がはっきりせず、「そんな段階でさらにAlertなんて表示できるかい!」と言われたわけなのだな。
Objective-Cでやってた頃はうまくいったような気もするのだが、Swiftや最近のiOSで仕様が変わったのかもしれん。まあいいや、覚えておけば。


具体的な書き方は以下。

    override func viewDidAppear(animated: Bool) {
        self.showAlert(title: "タイトル", message: "・メッセージ", actionTitle: "確認")
    }
    
    //AlertControllerで表示
    func showAlert(#title: String, message: String, actionTitle: String)
    {
        let alertCtl = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert) //UIAlertControllerStyle部分は省略可
//alertCtlにボタンごとの情報を追加する
        alertCtl.addAction(
            UIAlertAction(
                title: actionTitle,
                style: UIAlertActionStyle.Default, //デフォルトボタン
                handler: nil//ボタン押下時の処理はhandler:にクロージャとして書く
        )
        
        alertCtl.addAction(
            UIAlertAction(
                title: "キャンセル",
                style: UIAlertActionStyle.Cancel, //Cancelボタンは一番下に出る
                handler: nil)
        )
        
        alertCtl.addAction(
            UIAlertAction(
                title: "削除",
                style: UIAlertActionStyle.Destructive, //Destructiveは赤字になる
                handler: nil)
        )
        
//実際のAlert表示処理
        presentViewController(alertCtl, animated: true, completion: { println("アラート表示しました")}) //頭にself.を付けても付けなくてもどっちでもいい
//表示後の処理はcompletion:にクロージャとして書く
    }



なおiPadで表示する場合、preferredStyle: が.Alertならいいが、.ActionSheetの場合は以下のpopoverPresentationContollerのプロパティを設定してやらないとアプリが落ちる。
ActionSheetはiPhoneなら下からニョキって出るだけだけど、iPadの場合は画面上のどこかから吹き出しの形で出るみたいね。(ほとんど使ったことない)
だからどこから吹き出すのかなんかを指定してやらんといかんようだ。
なお、iPhoneで表示する場合は無視されるので、事前にデバイスを判断するif文などは必要ない。

        //For ipad And Univarsal Device
        alertCtl.popoverPresentationController?.sourceView = self.view

        alertCtl.popoverPresentationController?.sourceRect = CGRect(x: (self.view.frame.width/2), y: self.view.frame.height, width: 0, height: 0)

0 件のコメント:

コメントを投稿