3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[iOS14] UIAlertController内のUITextFieldに文字が入力されていない場合はUIAlertActionを選択できないようにする

Last updated at Posted at 2021-04-08

環境

  • Xcode 12.4
  • Swift 5.3.2

内容

iPhoneのPhotosアプリ内でアルバムを新規作成する際、
以下のようなアラートが表示されます。

Photos

初めは UIAlertActionSave アクションが選択できないようになっています。
UIAlertController 内の UITextField に文字を入力することで、
先のアクションが選択できるようになります。

今回はこちらを2つの方法で実現してみます。

下準備

適当にラベルとボタンを配置します。
ラベルはアラートで入力した文字列を表示するために用意しています。

SampleViewController

実装

①愚直に実装

SampleViewController.swift
final class SampleViewController: UIViewController {
    private let label = UILabel()
    private let button = UIButton(type: .system)

    private var saveAction: UIAlertAction!

    /*
    label, button等のUI処理
    */

    // ボタン押下時のアクション
    @objc private func showTextFieldAlert() {
        let alert = UIAlertController(title: "New Label",
                                      message: "Enter a name for the label.",
                                      preferredStyle: .alert)
        // textField
        alert.addTextField(configurationHandler: { [weak self] textField in
            textField.placeholder = "Label text"
            textField.delegate = self
        })
        // cancel action
        let cancelAction = UIAlertAction(title: "Cancel",
                                         style: .cancel)
        alert.addAction(cancelAction)
        // save action
        saveAction = UIAlertAction(title: "Save",
                                   style: .default,
                                   handler: { [weak alert] _ in
                                    let inputText = alert?.textFields?.first?.text
                                    self.label.text = inputText
                                   })
        saveAction.isEnabled = false
        alert.addAction(saveAction)

        present(alert, animated: true)
    }
}

extension SampleViewController: UITextFieldDelegate {
    func textFieldDidChangeSelection(_ textField: UITextField) {
        saveAction.isEnabled = !(textField.text?.trimmingCharacters(in: .whitespaces) ?? "").isEmpty
    }
}

改善したい点

  • 制御したいアクションをクラスのメンバ変数として用意している
  • ViewControllerに別のUITextFieldを用意する場合、Delegateのメソッド内でUITextFieldの判別をする必要がある

こちらを踏まえた上で別の方法に進みます。

②UIActionを活用

iOS14から追加された以下のプロパティとメソッドを利用します。

SampleViewController.swift
final class SampleViewController: UIViewController {
    private let label = UILabel()
    private let button = UIButton(type: .system)

    /*
    label, button等のUI処理
    */

    // ボタン押下時のアクション
    @objc private func showTextFieldAlert() {
        let alert = UIAlertController(title: "New Label",
                                      message: "Enter a name for the label.",
                                      preferredStyle: .alert)
        // cancel action
        let cancelAction = UIAlertAction(title: "Cancel",
                                         style: .cancel)
        alert.addAction(cancelAction)
        // save action
        let saveAction = UIAlertAction(title: "Save",
                                       style: .default) { [weak alert] _ in
            self.label.text = alert?.textFields?.first?.text
        }
        saveAction.isEnabled = false
        alert.addAction(saveAction)
        // textField
        let action = UIAction(handler: { action in
            guard let textField = action.sender as? UITextField else { return }
            saveAction.isEnabled = !(textField.text?.trimmingCharacters(in: .whitespaces) ?? "").isEmpty
        })
        alert.addTextField() { textField in
            textField.placeholder = "Label text"
            textField.addAction(action, for: .editingChanged)
        }

        present(alert, animated: true)
    }
}

これで①の改善したい点を解決できたかと思います。

実際の動作

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?