[Swift3.0] テキストフィールド付きUIAlertControllerを表示する

2016年9月4日(更新: 2016年9月16日)

iOSでアラートを表示するには UIAlertController を使います。デフォルトではアラートにはボタンなどがありませんので、自分で必要なものをつけることになります。

今回は、ボタン以外にテキストフィールドをアラート内に表示して、そこに入力されたテキストを受け取る方法を紹介します。

サンプルコード

新規作成したプロジェクト ViewController.swift にコピペして動作確認ができます。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let button = UIButton()
        button.setTitle("アラート表示", for: .normal)
        button.setTitleColor(UIColor.blue, for: .normal)
        button.addTarget(self, action: #selector(self.showTextInputAlert), for: .touchUpInside)
        button.sizeToFit()
        button.center = self.view.center
        self.view.addSubview(button)
    }
    
    func showTextInputAlert() {
        // テキストフィールド付きアラート表示
        
        let alert = UIAlertController(title: "タイトル", message: "メッセージ", preferredStyle: .alert)
        
        // OKボタンの設定
        let okAction = UIAlertAction(title: "OK", style: .default, handler: {
            (action:UIAlertAction!) -> Void in
            
            // OKを押した時入力されていたテキストを表示
            if let textFields = alert.textFields {
                
                // アラートに含まれるすべてのテキストフィールドを調べる
                for textField in textFields {
                    print(textField.text!)
                }
            }
        })
        alert.addAction(okAction)
        
        // キャンセルボタンの設定
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
        alert.addAction(cancelAction)
        
        // テキストフィールドを追加
        alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in
            textField.placeholder = "テキスト"
        })
        
        // 複数追加したいならその数だけ書く
        // alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in
        //     textField.placeholder = "テキスト"
        // })
        
        alert.view.setNeedsLayout() // シミュレータの種類によっては、これがないと警告が発生
        
        // アラートを画面に表示
        self.present(alert, animated: true, completion: nil)
    }
}

テキストフィールドを追加しているのは以下のコードです。

alert.addTextField(configurationHandler: {(textField: UITextField!) -> Void in
        // ここでテキストフィールドのカスタマイズができる
})

以前は addTextFieldWithConfigurationHandler という名前でしたが、Swift3から addTextField となりました。

変数 textField のメソッドを設定することで、普通のテキストフィールドと同じように設定ができます。

実行結果

このコードを実行すると、ボタンが中央に表示された画面が表示されます。

このボタンを押すと、テキストフィールド付きのアラートが表示されます。アラート内のテキストフィールドに文字を入力してからOKボタンを押すと、コンソールに入力したテキストが表示されることが確認できます。

テキストフィールド付きUIAlertControllerのサンプル

注意点しては、アラートを表示する前に setNeedsLayout を呼び出さないと、iPhone6などのシミュレータでは以下のような警告が表示されます。

the behavior of the UICollectionViewFlowLayout is not defined because:
the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values.
The relevant UICollectionViewFlowLayout instance is <_UIAlertControllerCollectionViewFlowLayout: 0x7f917278ac50>, and it is attached to <UICollectionView: 0x7f9174066c00; frame = (0 120.667; 270 44); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x7f917278b940>; layer = <CALayer: 0x7f917278b2b0>; contentOffset: {0, 0}; contentSize: {0, 0}> collection view layout: <_UIAlertControllerCollectionViewFlowLayout: 0x7f917278ac50>.
Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.

これは不具合としてAppleに報告されているようです。

XCODE iphone 6 plus and 6s plus shows warning when display UIAlertViewController

以上、アラート内にテキストフィールドを表示して入力されたテキストを受け取る方法でした。

コメントを残す

メールアドレスが公開されることはありません。