Get input value from TextField in iOS alert in Swift

119,423

Solution 1

Updated for Swift 3 and above:

//1. Create the alert controller.
let alert = UIAlertController(title: "Some Title", message: "Enter a text", preferredStyle: .alert)

//2. Add the text field. You can configure it however you need.
alert.addTextField { (textField) in
    textField.text = "Some default text"
}

// 3. Grab the value from the text field, and print it when the user clicks OK.
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
    let textField = alert.textFields![0] // Force unwrapping because we know it exists.
    print("Text field: \(textField.text)")
}))

// 4. Present the alert.
self.present(alert, animated: true, completion: nil)

Swift 2.x

Assuming you want an action alert on iOS:

//1. Create the alert controller.            
var alert = UIAlertController(title: "Some Title", message: "Enter a text", preferredStyle: .Alert)

//2. Add the text field. You can configure it however you need.
alert.addTextFieldWithConfigurationHandler({ (textField) -> Void in
    textField.text = "Some default text."
})

//3. Grab the value from the text field, and print it when the user clicks OK. 
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { [weak alert] (action) -> Void in
    let textField = alert.textFields![0] as UITextField
    println("Text field: \(textField.text)")
}))

// 4. Present the alert.
self.presentViewController(alert, animated: true, completion: nil)

Solution 2

Swift 5

You can use the below extension for your convenience.

Usage inside a ViewController:

showInputDialog(title: "Add number",
                subtitle: "Please enter the new number below.",
                actionTitle: "Add",
                cancelTitle: "Cancel",
                inputPlaceholder: "New number",
                inputKeyboardType: .numberPad, actionHandler:
                        { (input:String?) in
                            print("The new number is \(input ?? "")")
                        })

The extension code:

extension UIViewController {
    func showInputDialog(title:String? = nil,
                         subtitle:String? = nil,
                         actionTitle:String? = "Add",
                         cancelTitle:String? = "Cancel",
                         inputPlaceholder:String? = nil,
                         inputKeyboardType:UIKeyboardType = UIKeyboardType.default,
                         cancelHandler: ((UIAlertAction) -> Swift.Void)? = nil,
                         actionHandler: ((_ text: String?) -> Void)? = nil) {
        
        let alert = UIAlertController(title: title, message: subtitle, preferredStyle: .alert)
        alert.addTextField { (textField:UITextField) in
            textField.placeholder = inputPlaceholder
            textField.keyboardType = inputKeyboardType
        }
        alert.addAction(UIAlertAction(title: actionTitle, style: .default, handler: { (action:UIAlertAction) in
            guard let textField =  alert.textFields?.first else {
                actionHandler?(nil)
                return
            }
            actionHandler?(textField.text)
        }))
        alert.addAction(UIAlertAction(title: cancelTitle, style: .cancel, handler: cancelHandler))
        
        self.present(alert, animated: true, completion: nil)
    }
}

Solution 3

In Swift5 ans Xcode 10

Add two textfields with Save and Cancel actions and read TextFields text data

func alertWithTF() {
    //Step : 1
    let alert = UIAlertController(title: "Great Title", message: "Please input something", preferredStyle: UIAlertController.Style.alert )
    //Step : 2
    let save = UIAlertAction(title: "Save", style: .default) { (alertAction) in
        let textField = alert.textFields![0] as UITextField
        let textField2 = alert.textFields![1] as UITextField
        if textField.text != "" {
            //Read TextFields text data
            print(textField.text!)
            print("TF 1 : \(textField.text!)")
        } else {
            print("TF 1 is Empty...")
        }

        if textField2.text != "" {
            print(textField2.text!)
            print("TF 2 : \(textField2.text!)")
        } else {
            print("TF 2 is Empty...")
        }
    }

    //Step : 3
    //For first TF
    alert.addTextField { (textField) in
        textField.placeholder = "Enter your first name"
        textField.textColor = .red
    }
    //For second TF
    alert.addTextField { (textField) in
        textField.placeholder = "Enter your last name"
        textField.textColor = .blue
    }

    //Step : 4
    alert.addAction(save)
    //Cancel action
    let cancel = UIAlertAction(title: "Cancel", style: .default) { (alertAction) in }
    alert.addAction(cancel)
    //OR single line action
    //alert.addAction(UIAlertAction(title: "Cancel", style: .default) { (alertAction) in })

    self.present(alert, animated:true, completion: nil)

}

For more explanation https://medium.com/@chan.henryk/alert-controller-with-text-field-in-swift-3-bda7ac06026c

Solution 4

Swift version: 5.+

Create a new TextField variable in current scope and assign it to alertTextField in alert.addTextField completion handler. Use textField's value inside UIAlertAction completion handler.

@IBAction func addButtonPressed(_ sender: UIBarButtonItem) {
          //Variable to store alertTextField
            var textField = UITextField()
            
            let alert = UIAlertController(title: "Add new item", message: "", preferredStyle: .alert)
            alert.addTextField { alertTextField in
                alertTextField.placeholder = "Create new item"
                
                //Copy alertTextField in local variable to use in current block of code
                textField = alertTextField
            }
            
            let action = UIAlertAction(title: "Add item", style: .default) { action in
                //Prints the alertTextField's value
                print(textField.text!)
            }
            
            alert.addAction(action)
            present(alert, animated: true, completion: nil)
        }
Share:
119,423
ntoonio
Author by

ntoonio

I can tell if a dinosaur in movies are fake or not "Please quote me in the future" - Me

Updated on August 31, 2021

Comments

  • ntoonio
    ntoonio over 2 years

    I'm trying to make an alert message with input, and then get the value from the input. I've found many good tutorials how to make the input text field. but I can't get the value from the alert.

  • Andy Ibanez
    Andy Ibanez over 9 years
    Not a problem. Please remember to mark this as Accepted if it helped you. Thanks!
  • Sjharrison
    Sjharrison about 9 years
    Hi @AndyIbanez I'm trying to implement your code on my app, however its stating the error "Use of undeclared identifier var" I'm new to Xcode so apologies if this is a basic error on my behalf
  • Andy Ibanez
    Andy Ibanez about 9 years
    @Sjharrison My code is for Swift. The only reason I can think of that would cause you troubles with the var keyword is if you were writing in Objective-C.
  • Sjharrison
    Sjharrison about 9 years
    Ahh i see! yeah I'm using Xcode, only been doing this a few hours so over tired and still learning!
  • Andrej
    Andrej over 7 years
    Can anyone explain why the [weak alert]? I'm looking at Swift 3.
  • Andy Ibanez
    Andy Ibanez over 7 years
    @Andrej It's to avoid leaking memory. To better understand, read about memory management in Swift.
  • Rais Iqbal
    Rais Iqbal about 7 years
    Worked after small modifications. Thanks, Buddy.
  • Andy Ibanez
    Andy Ibanez about 7 years
    @RAISIQBAL What modifications did you do? Please let me know to see if updating this answer will be necessary.
  • James
    James about 7 years
    For Swift 3 alert in step 3. is optional, needed "?" let textField = alert?.textFields![0] // Force unwrapping because we know it exists. print("Text field: \(textField?.text)")
  • Umit Kaya
    Umit Kaya almost 7 years
    Maybe you can add cancel action as well in your answer.
  • Andy Ibanez
    Andy Ibanez over 6 years
    Many people have tried to add the Cancel button to this answer. Please stop trying to do that. If it gets approved, I will revert it. The answer as it is already addresses the author's question. Let adding the Cancel button be an exercise for the reader of this answer.
  • Bishal Ghimire
    Bishal Ghimire almost 5 years
    just note that if you are going to present "Add" action make sure the style if "default" not "destructive" -- alert.addAction(UIAlertAction(title: actionTitle, style: .default ...
  • Vaibhav Jhaveri
    Vaibhav Jhaveri over 3 years
    How to assign delegate for the textfield?
  • Vaibhav Jhaveri
    Vaibhav Jhaveri over 3 years
    @Gunhan How to assign delegate for the textfield?
  • Gunhan
    Gunhan over 3 years
    @VaibhavJhaveri just add one more parameter to the function e.g. delegate: UITextFieldDelegate? = nil, and inside the function where we add the textfield assign it e.g. textField.delegate = delegate
  • Vaibhav Jhaveri
    Vaibhav Jhaveri over 3 years
    @Gunhan That worked. However, the text field is displayed with it being the first responder. I want to turn that off. how can I do that? I want to open custom view when I click on the textfield
  • FrugalResolution
    FrugalResolution about 3 years
    Don't forget the iPad popover: // iPad popOver: if let popoverController = alert.popoverPresentationController { popoverController.sourceView = self.view popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0) popoverController.permittedArrowDirections = [] }