Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable UIAlertAction of UIAlertController only after input is validated

I am using a UIAlertController to present a dialog with a UITextField and one UIAlertAction button labeled "Ok". How do I disable the button until a number of characters (say 5 characters) are input into the UITextField?

like image 368
saintjab Avatar asked Aug 30 '15 16:08

saintjab


1 Answers

With Swift 5.3 and iOS 14, you can use Combine framework and NotificationCenter to track UITextField.textDidChangeNotification notifications for a given UITextField.


The following code shows a possible implementation in order to enable the button of a UIAlertController according to the character count of its textField:

import UIKit
import Combine

class ViewController: UIViewController {

    var cancellable: AnyCancellable?

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .systemBackground

        let action = UIAction(
            title: "Change title",
            handler: { [unowned self] _ in
                self.presentAlert()
            }
        )
        let barButtonItem = UIBarButtonItem(primaryAction: action)
        navigationItem.rightBarButtonItem = barButtonItem
    }

}
extension ViewController {

    func presentAlert() {
        let alertController = UIAlertController(
            title: "Change title",
            message: nil,
            preferredStyle: .alert
        )
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { _ in
            print("Cancelled")
        }
        let renameAction = UIAlertAction(
            title: "Rename",
            style: .default
        ) { [unowned alertController] action in
            print("Renamed: \(alertController.textFields!.first!.text!)")
        }
        renameAction.isEnabled = false

        alertController.addAction(cancelAction)
        alertController.addAction(renameAction)
        alertController.addTextField(configurationHandler: { textField in
            self.cancellable = NotificationCenter.default
                .publisher(for: UITextField.textDidChangeNotification, object: textField)
                .sink(receiveValue: { _ in
                    let textCount = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines).count ?? 0
                    renameAction.isEnabled = textCount >= 5 // min 5 characters
                })
        })
        present(alertController, animated: true)
    }

}
like image 104
Imanou Petit Avatar answered Sep 28 '22 20:09

Imanou Petit