Get input value from TextField in iOS alert in Swift
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)
}
ntoonio
I can tell if a dinosaur in movies are fake or not "Please quote me in the future" - Me
Updated on August 31, 2021Comments
-
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 over 9 yearsNot a problem. Please remember to mark this as Accepted if it helped you. Thanks!
-
Sjharrison about 9 yearsHi @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 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 about 9 yearsAhh i see! yeah I'm using Xcode, only been doing this a few hours so over tired and still learning!
-
Andrej over 7 yearsCan anyone explain why the
[weak alert]
? I'm looking at Swift 3. -
Andy Ibanez over 7 years@Andrej It's to avoid leaking memory. To better understand, read about memory management in Swift.
-
Rais Iqbal about 7 yearsWorked after small modifications. Thanks, Buddy.
-
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 about 7 yearsFor 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 almost 7 yearsMaybe you can add cancel action as well in your answer.
-
Andy Ibanez over 6 yearsMany 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 almost 5 yearsjust 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 over 3 yearsHow to assign delegate for the textfield?
-
Vaibhav Jhaveri over 3 years@Gunhan How to assign delegate for the textfield?
-
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 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 about 3 yearsDon'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 = [] }