class x: UIViewController {
let fromLocationLbl = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
let editTextField = UITextField()
let alertController = UIAlertController(title: "Alert!", message: "Please enter from location", preferredStyle: .alert)
alertController.addTextField { editTextField in
editTextField.placeholder = "Enter correct name"
// editTextField.text = self.fromLocationLbl.text
}
let confirmAction = UIAlertAction(title: "Change", style: UIAlertActionStyle.default) { (UIAlertAction) in
print(editTextField.text) ///////printing optional("")
self.fromLocationLbl.text = editTextField.text
}
alertController.addAction(confirmAction)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
}
editTextField isn't the same UITextField as you're adding to alert. In addTextField closure, editTextField is just name for parameter of closure which can be replaced with any other name
alertController.addTextField { textField in
textField.placeholder = "Enter correct name"
// textField.text = self.fromLocationLbl.text
}
You need to get reference for first text field in your alertController
let confirmAction = UIAlertAction(title: "Change", style: .default) { _ in
self.fromLocationLbl.text = alertController.textFields?.first?.text
}
Related
I am trying to modulraise my code I am able to create extension for alertController without target
extension UIViewController {
func showAlert(title: String, message: String) {
let alertController = UIAlertController(title: title, message:
message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {_ in
}))
self.present(alertController, animated: true, completion: nil)
}
}
but I am not sure how to create extension which have target and textfield(how to create and call that in viewcontroller)
my code for which i am trying to create extension
let alertController = UIAlertController(title: "enter name", message: nil, preferredStyle: .alert)
let addAction = UIAlertAction(title: "Ok", style: .default) {_ in
guard let name = alertController.textFields?.first?.text else { return }
let newTask = Task(name: name)
self.toDoStore?.add(newTask, at: 0)
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.insertRows(at: [indexPath], with: .automatic)
}
addAction.isEnabled = false
let cancelAction = UIAlertAction(title: CANCEL_ACTION, style: .cancel, handler: nil)
alertController.addTextField { textField in
textField.placeholder = "enter name.."
textField.addTarget(self, action: #selector(self.handleTextChanged), for: .editingChanged)
}
alertController.addAction(addAction);
alertController.addAction(cancelAction);
present(alertController, animated: true, completion: nil)
You could try the below extension that I'm using made a few changes according to your requirements.
extension UIViewController {
func showAlert(_ title: String?,
message: String?,
actions: [String: UIAlertAction.Style] = [:],
handler: ((UIAlertAction) -> Void)? = nil,
textFields: [((UITextField) -> Void)] = []) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
if actions.isEmpty {
alert.addAction(UIAlertAction(title: "Okay", style: .default))
} else {
for action in actions {
alert.addAction(UIAlertAction(title: action.key, style: action.value, handler: handler))
}
}
for textField in textFields {
alert.addTextField(configurationHandler: textField)
}
present(alert, animated: true)
}
}
A bit of advise you can always check how the parameters that you pass are accepted by the system API and customize your own function in a similar way.
I have a action sheet and I open a alert with them with the following codelins:
func showActionSheet(postId: String) {
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let action = UIAlertAction(title: NSLocalizedString("Beitrag melden", comment: ""), style: .default, handler: { _ in
self.alertBeitrageMelden(postId: postId)
})
actionSheet.addAction(action)
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
self.present(actionSheet, animated: true, completion: nil)
}
I now want to store the input of the textfield inside the alert in Firebase:
func alertBeitrageMelden(postId: String){
// Create the action buttons for the alert.
let defaultAction = UIAlertAction(title: "Melden", style: .default) { (action) in
let ref = Database.database().reference().child("gemeldeteBeitraege").child(postId)
ref.setValue(["postId": postId, "reason": self.textFieldAlert])
}
let cancelAction = UIAlertAction(title: "Abbrechen", style: .cancel) { (action) in
// Respond to user selection of the action.
}
let alert = UIAlertController(title: "Beitrag melden", message: "Wieso möchtest du den Beitrag melden?", preferredStyle: .alert)
alert.addTextField { (textField) in
textField.placeholder = ""
if textField.text?.count ?? 0 > 0 {
self.textFieldAlert = textField.text!
}
}
alert.addAction(cancelAction)
alert.addAction(defaultAction)
self.present(alert, animated: true) {
}
}
I don't get any data of the textField.
Thanks in advance for your help!
You need
if let te = alert.textFields?.first?.text , te.count > 0 {
let ref = Database.database().reference().child("gemeldeteBeitraege").child(postId)
ref.setValue(["postId": postId, "reason":te])
}
As this self.textFieldAlert = textField.text! will store an empty initial value , and move this line
let alert = UIAlertController(title: "Beitrag melden", message: "Wieso möchtest du den Beitrag melden?", preferredStyle: .alert)
top of fucntion , so you can access it inside the alert action
func alertBeitrageMelden(postId: String) {
let alert = UIAlertController(title: "Beitrag melden", message: "Wieso möchtest du den Beitrag melden?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Melden", style: .default) { (action) in
if let te = alert.textFields?.first?.text , te.count > 0 {
let ref = Database.database().reference().child("gemeldeteBeitraege").child(postId)
ref.setValue(["postId": postId, "reason":te])
}
})
alert.addAction(UIAlertAction(title: "Abbrechen", style: .cancel) { (action) in
// Respond to user selection of the action.
})
alert.addTextField { (textField) in
textField.placeholder = ""
}
self.present(alert, animated: true)
}
You can also do this by keeping a reference to the alert's textfield
var alertTexf:UITextField!
func alertBeitrageMelden(postId: String){
let alert = UIAlertController(title: "Beitrag melden", message: "Wieso möchtest du den Beitrag melden?", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Melden", style: .default) { (action) in
if let te = self.alertTexf.text , te.count > 0 {
let ref = Database.database().reference().child("gemeldeteBeitraege").child(postId)
ref.setValue(["postId": postId, "reason":te])
}
})
alert.addAction(UIAlertAction(title: "Abbrechen", style: .cancel) { (action) in
// Respond to user selection of the action.
})
alert.addTextField { (textField) in
textField.placeholder = ""
self.alertTexf = textField
}
self.present(alert, animated: true)
}
You can get your textField from your alertController using alert.textFields?.first.
Example:
func alertBeitrageMelden(postId: String){
// Create the action buttons for the alert.
let alert = UIAlertController(title: "Beitrag melden", message: "Wieso möchtest du den Beitrag melden?", preferredStyle: .alert)
alert.addTextField { (textField) in
textField.placeholder = ""
}
let defaultAction = UIAlertAction(title: "Melden", style: .default) { (action) in
if let textFieldAlert = alert.textFields?.first?.text, textFieldAlert.count > 0 {
let ref = Database.database().reference().child("gemeldeteBeitraege").child(postId)
ref.setValue(["postId": postId, "reason": textFieldAlert])
}
}
let cancelAction = UIAlertAction(title: "Abbrechen", style: .cancel) { (action) in
// Respond to user selection of the action.
}
alert.addAction(cancelAction)
alert.addAction(defaultAction)
self.present(alert, animated: true) {
}
}
alert.addTextField { textField in
}
This is alert's configuration handler where you can change properties of text field which will be added. But setting some text variable here doesn't make any sense because text of text field is empty in this moment.
Your goal should be get text of text field in moment when you need it, in this case in UIAlertAction's handler
So create alert before you declare its actions and add text field
let alert = UIAlertController(title: "Beitrag melden", message: "Wieso möchtest du den Beitrag melden?", preferredStyle: .alert)
alert.addTextField { textField in
textField.placeholder = ""
}
then in default action check if text of this text field isn't empty and if isn't save this text to Firebase
let defaultAction = UIAlertAction(title: "Melden", style: .default) { _ in
if let text = alert.textFields?.first?.text, !text.isEmpty {
let ref = Database.database().reference().child("gemeldeteBeitraege").child(postId)
ref.setValue(["postId": postId, "reason": text])
}
}
I have the following code which uses an alert to gather an email address from the user. I'd like to specify the keyboard type but haven't been able to figure out how to do that inside an alert. Is anyone able to help show how to set .keyboardType = UIKeyboardType.emailAddress?
var userInput: String = ""
let prompt = UIAlertController.init(title: nil, message: "Enter your email address", preferredStyle: UIAlertControllerStyle.alert)
let okAction = UIAlertAction.init(title: "OK", style: UIAlertActionStyle.default) { (action) in
userInput = prompt.textFields![0].text
if (userInput!.isEmpty) {
return
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (action) in
print(action)
}
prompt.addTextField(configurationHandler: nil)
prompt.addAction(okAction)
prompt.addAction(cancelAction)
self.view?.window?.rootViewController?.present(prompt, animated: true, completion: nil)
Switch this with the addTextfield line. Basically this is where you do the configuration for your textfield as it implies.
prompt.addTextField { (textfield) in
textfield.keyboardType = .emailAddress
}
I want to save the data from whatever is being typed from the text to be saved when you press the save button. Here is my code:
#IBAction func buttonTappedToSetAReminder(sender: AnyObject) {
let alertController = UIAlertController(title: "Reminders", message: "", preferredStyle: UIAlertControllerStyle.Alert)
let saveAction = UIAlertAction(title: "Save", style: UIAlertActionStyle.Default, handler: {
alert -> Void in
_ = alertController.textFields![0] as UITextField
})
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Default, handler: {
(action : UIAlertAction!) -> Void in
})
alertController.addTextFieldWithConfigurationHandler { (textField : UITextField!) -> Void in
textField.placeholder = "Put a reminder!!!"
}
alertController.addAction(saveAction)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
Within your save action handler, you want to get
the textField from the alertView
then the text from the textField
Example
let alertController = UIAlertController(title: "Reminders", message: "", preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save", style: .Default) { action in
if let textField = alert.textFields?[0], text = textField.text {
// Do something with text
} else {
// Didn't get text
}
}
...
let textField = alertController.textFields![0] as UITextField
// do something with textField.text
It seems like NSUserDefaults/UserDefaults is an option:
Swift 2:
let textField = alertController.textFields![0]
NSUserDefaults.standardUserDefaults().setObject(textField.text, forKey: "text")
Swift 3:
let textField = alertController.textFields![0]
UserDefaults.standard.set(textField.text, forKey("text")
In one of my viewController, I want to make an alert box appear that prompts the user to type this information.Then, I want the user to store this input using NSUserDefaults. How can I achieve this?
Thank you in advance!
Check this out:
let alertController = UIAlertController(title: "Email?", message: "Please input your email:", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in
guard let textFields = alertController.textFields,
textFields.count > 0 else {
// Could not find textfield
return
}
let field = textFields[0]
// store your data
UserDefaults.standard.set(field.text, forKey: "userEmail")
UserDefaults.standard.synchronize()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addTextField { (textField) in
textField.placeholder = "Email"
}
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
SWIFT 3
func presentAlert() {
let alertController = UIAlertController(title: "Email?", message: "Please input your email:", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in
if let emailTextField = alertController.textFields?[0] {
// do your stuff with emailTextField
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
alertController.addTextField { (textField) in
textField.placeholder = "Email"
}
alertController.addAction(confirmAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
In swift 3
let alertController = UIAlertController(title: "SecureStyle", message: "SecureStyle AlertView.", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addTextFieldWithConfigurationHandler { (textField : UITextField) -> Void in
textField.secureTextEntry = true
textField.placeholder = "Password"
}
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel) { (result : UIAlertAction) -> Void in
print("Cancel")
}
let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (result : UIAlertAction) -> Void in
print(alertController.textFields?.first?.text)
}
alertController.addAction(cancelAction)
alertController.addAction(okAction)
self.presentViewController(alertController, animated: true, completion: nil)