如何在 Swift 中向 UIAlertController 添加 TextField

我试图显示一个 UIAlertController和一个 UITextView。当我添加行:

    //Add text field
alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
}

我得到一个 Runtime错误:

致命错误: 在取消包装可选值时意外发现 nil

    let alertController: UIAlertController = UIAlertController(title: "Find image", message: "Search for image", preferredStyle: .Alert)


//cancel button
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
//cancel code
}
alertController.addAction(cancelAction)


//Create an optional action
let nextAction: UIAlertAction = UIAlertAction(title: "Search", style: .Default) { action -> Void in
let text = (alertController.textFields?.first as! UITextField).text
println("You entered \(text)")
}
alertController.addAction(nextAction)


//Add text field
alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
textField.textColor = UIColor.greenColor()
}
//Present the AlertController
presentViewController(alertController, animated: true, completion: nil)

这是在我的 ViewController中通过 IBAction呈现的。

我已经从 给你下载了代码,它工作得很好。我复制并粘贴了这个方法到我的代码中,它中断了。自我在最后一行上的存在没有影响。

109440 次浏览

So I started checking to see what could possibly have been different in my code to the working code. I noticed that my ViewController extends

UITextFieldDelegate

Which apparently means that I need to set the delegate of any child UITextView:

alertController.addTextFieldWithConfigurationHandler { (textField) -> Void in
searchTextField = textField
searchTextField?.delegate = self //REQUIRED
searchTextField?.placeholder = "Enter your search terms"
}

Swift 5.1

alert.addTextField { (textField) in
textField.placeholder = "Enter First Name"
}

Use this code, I am running this code in my app successfully.

@IBAction func addButtonClicked(sender : AnyObject){
let alertController = UIAlertController(title: "Add New Name", message: "", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addTextFieldWithConfigurationHandler { (textField : UITextField!) -> Void in
textField.placeholder = "Enter Second Name"
}
let saveAction = UIAlertAction(title: "Save", style: UIAlertActionStyle.Default, handler: { alert -> Void in
let firstTextField = alertController.textFields![0] as UITextField
let secondTextField = alertController.textFields![1] as UITextField
})
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: {
(action : UIAlertAction!) -> Void in })
alertController.addTextFieldWithConfigurationHandler { (textField : UITextField!) -> Void in
textField.placeholder = "Enter First Name"
}
    

alertController.addAction(saveAction)
alertController.addAction(cancelAction)
    

self.presentViewController(alertController, animated: true, completion: nil)
}

Edited: Swift 3.0 version

@IBAction func addButtonClicked(_ sender: UIButton){
let alertController = UIAlertController(title: "Add New Name", message: "", preferredStyle: .alert)
alertController.addTextField { (textField : UITextField!) -> Void in
textField.placeholder = "Enter Second Name"
}
let saveAction = UIAlertAction(title: "Save", style: .default, handler: { alert -> Void in
let firstTextField = alertController.textFields![0] as UITextField
let secondTextField = alertController.textFields![1] as UITextField
print("firstName \(firstTextField.text), secondName \(secondTextField.text)")
})
let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: { (action : UIAlertAction!) -> Void in })
alertController.addTextField { (textField : UITextField!) -> Void in
textField.placeholder = "Enter First Name"
}


alertController.addAction(saveAction)
alertController.addAction(cancelAction)
    

self.present(alertController, animated: true, completion: nil)
}

To add a text field in Swift 3.0:

let alertController = UIAlertController(title: "Title", message: "", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Save", style: .default, handler: { alert -> Void in
let textField = alertController.textFields![0] as UITextField
// do something with textField
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
alertController.addTextField(configurationHandler: {(textField : UITextField!) -> Void in
textField.placeholder = "Search"
})
self.present(alertController, animated: true, completion: nil)

Great answer a slight modification to show how the textfield can be used:

func addRow (row: Int, bodin: String, flag: Int) {
let alertController = UIAlertController(title: bodin, message: "", preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Save", style: .default, handler: {
alert -> Void in
_ = alertController.textFields![0] as UITextField


}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))


alertController.addTextField(configurationHandler: {(textField : UITextField!) -> Void in
switch flag {
case 0:
textField.keyboardType = UIKeyboardType.phonePad
textField.placeholder = "Enter Number"
case 1:
textField.keyboardType = UIKeyboardType.emailAddress
textField.placeholder = "Enter Email"
default:
break
}


})

How to add textField to AlertView? Let's keep it short and simple.

This works for Swift 3.0 and above.

var nameField: UITextField?
let alertController = UIAlertController(title: "Add Number", message: nil, preferredStyle: .alert)
// Add textfield to alert view
alertController.addTextField { (textField) in
nameField = textField
}

First, you instantiate an object of UIAlertController and then you add a text field to it by accessing addTextField member of UIAlertController class.

add TextField to UIAlertController and TextField text Display on UILabel in Swift

let alert = UIAlertController(title: "Alert", message: "", preferredStyle: .alert)


alert.addTextField { (textField) in
textField.placeholder = "First Name"
}
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert?.textFields![0]
self.label.text = textField?.text  }))


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

For Swift 4.0, You can use this sample of code succesfully tested in my project:

@IBAction func withdrawTapped(_ sender: UIButton) {


let alertController = UIAlertController(title: "Token withdraw", message: "", preferredStyle: .alert)


let withdrawAction = UIAlertAction(title: "Withdraw", style: .default) { (aciton) in


let text = alertController.textFields!.first!.text!


if !text.isEmpty {
self.presentAlert(
title: "Succesful",
message: "You made request for withdraw \(textField.text) tokens")
}
}


let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
}


alertController.addTextField { (textField) in
textField.placeholder = "999"
textField.keyboardType = .decimalPad
}


alertController.addAction(withdrawAction)
alertController.addAction(cancelAction)


self.present(alertController, animated: true, completion: nil)
}

Solution:

Swift 4.2

Try the following lines and see if it works:

let alertController = UIAlertController(title: "Add New Name", message: "", preferredStyle: .alert)


alertController.addTextField { (textField : UITextField!) -> Void in
textField.placeholder = "Enter Second Name"
}


let saveAction = UIAlertAction(title: "Save", style: .default, handler: { alert -> Void in
let firstTextField = alertController.textFields![0] as UITextField
let secondTextField = alertController.textFields![1] as UITextField
})


let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil )


alertController.addTextField { (textField : UITextField!) -> Void in
textField.placeholder = "Enter First Name"
}


alertController.addAction(saveAction)
alertController.addAction(cancelAction)


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

Hope it helps.

In Swift 4.2 and Xcode 10.1

Alert with two Textfields and Read TextField text data and present alert on top of all views.

func alertWithTF(title: String, message: String) {
//Step : 1
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)


//Step : 2
alert.addAction (UIAlertAction(title: "Save", style: .default) { (alertAction) in
let textField = alert.textFields![0]
let textField2 = alert.textFields![1]
if textField.text != "" {
//Read textfield data
print(textField.text!)
print("TF 1 : \(textField.text!)")
} else {
print("TF 1 is Empty...")
}
if textField2.text != "" {
//Read textfield data
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
}


//Cancel action
alert.addAction(UIAlertAction(title: "Cancel", style: .default) { (alertAction) in })
self.present(alert, animated:true, completion: nil)


}

If you want to present aleert on top of all views.

Here from above code remove this last line self.present(alert, animated:true, completion: nil) and add below code.

//Present alert on top of all views.
let alertWindow = UIWindow(frame: UIScreen.main.bounds)
alertWindow.rootViewController = UIViewController()
alertWindow.windowLevel = UIWindowLevelAlert + 1


alertWindow.makeKeyAndVisible()


alertWindow.rootViewController?.present(alert, animated:true, completion: nil)

Now call like this

alertWithTF(title: "This is title", message: "This is message")

To add alertController with one textField (Swift 5)

func openAlert(){
let alertController = UIAlertController(title: "Title", message: "", preferredStyle: .alert)
alertController.addTextField { (textField : UITextField!) -> Void in
textField.placeholder = "Enter name"
}


let saveAction = UIAlertAction(title: kAlertConfirm, style: .default, handler: { alert -> Void in
if let textField = alertController.textFields?[0] {
if textField.text!.count > 0 {
print("Text :: \(textField.text ?? "")")
}
}
})


let cancelAction = UIAlertAction(title: kAlertCancel, style: .default, handler: {
(action : UIAlertAction!) -> Void in })


alertController.addAction(cancelAction)
alertController.addAction(saveAction)


alertController.preferredAction = saveAction


self.present(alertController, animated: true, completion: nil)
}

Swift5

First class conforms to the UITextFieldDelegate , then create new textField property

    private var myTextField : UITextField?


// now where u want to add code
let alertContoller = UIAlertController.init(title: "Add", message: "My message to user", preferredStyle: .alert)
alertContoller.addTextField { (textField) in
// make sure your outside any property should be accessed with self here
self.myTextField = textField
//Important step assign textfield delegate to self
self.myTextField?.delegate = self
self.myTextField?.placeholder = self.textFieldPlaceholderText
}
let action = UIAlertAction.init(title: "Ok", style: .default) { action in
print("Alert tapped")
}
alertContoller.addAction(action)
present(alertContoller, animated: true, completion:nil)

Thanks

private func showLoginAlert() {
let loginAlert = UIAlertController(title: "Login Using Credentials", message: nil, preferredStyle: .alert)
loginAlert.view.tintColor = .systemBlue


loginAlert.addTextField { usernameField in
usernameField.font = .systemFont(ofSize: 17.0)
usernameField.placeholder = "Username"
}
loginAlert.addTextField { passwordField in
passwordField.font = .systemFont(ofSize: 17.0)
passwordField.isSecureTextEntry = true
passwordField.placeholder = "Password"
}


let cancelAction = UIAlertAction(title: "Cancel",
style: .destructive,
handler: { _ in
// self.handleUsernamePasswordCanceled(loginAlert: loginAlert)
})
loginAlert.addAction(cancelAction)


let loginAction = UIAlertAction(title: "Login",
style: .default,
handler: { _ in
// self.handleUsernamePasswordEntered(loginAlert: loginAlert)
})
loginAlert.addAction(loginAction)
loginAlert.preferredAction = loginAction
present(loginAlert, animated: true, completion: nil)
}

Swift 5

UIAlertController with UITextfield in latest Apple Swift version 5.1.3

Create a lazy variable of UIAlertController in your UIViewController , Add UITextFieldDelegate , Show Alert on UIButton Action :

class  YourViewController: UIViewController,UITextFieldDelegate {


//Create Alert Controller Object here
lazy var alertEmailAddEditView:UIAlertController = {


let alert = UIAlertController(title:"My App", message: "Customize Add/Edit Email Pop Up", preferredStyle:UIAlertController.Style.alert)


//ADD TEXT FIELD (YOU CAN ADD MULTIPLE TEXTFILED AS WELL)
alert.addTextField { (textField : UITextField!) in
textField.placeholder = "Enter  emails"
textField.delegate = self
}


//SAVE BUTTON
let save = UIAlertAction(title: "Save", style: UIAlertAction.Style.default, handler: { saveAction -> Void in
let textField = alert.textFields![0] as UITextField
print("value entered by user in our textfield is: \(textField.text)")
})
//CANCEL BUTTON
let cancel = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.default, handler: {
(action : UIAlertAction!) -> Void in })




alert.addAction(save)
alert.addAction(cancel)


return alert
}()




//MARK:- UIButton Action for showing Alert Controller
@objc func buttonClicked(btn:UIButton){
self.present(alertEmailAddEditView, animated: true, completion: nil)
}


//MARK:- UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}

Happy Coding!! :)