I want the user to press a button, and then for them to be able to see an alert where they can enter an input (to set a price for a service). The other logic involves saving data to a database, which is not really relevant to my problem.
I am using the following example:
https://stackoverflow.com/a/30139623/2411290
It definitely works, in that it shows the alert correctly, but once I include
print("Amount: \(self.tField.text)")
"self.tField.text" is not recognized. The specific error I get is:
value of type 'testVC' has no member 'tField'
#IBAction func setAmount(_ sender: Any) {
var tField: UITextField!
func configurationTextField(textField: UITextField!)
{
print("generating textField")
textField.placeholder = "Enter amount"
tField = textField
}
func handleCancel(alertView: UIAlertAction!)
{
print("Cancelled")
}
let alert = UIAlertController(title: "Set price of service", message: "", preferredStyle: .alert)
alert.addTextField(configurationHandler: configurationTextField)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:handleCancel))
alert.addAction(UIAlertAction(title: "Done", style: .default, handler:{ (UIAlertAction) in
print("Done !!")
}))
self.present(alert, animated: true, completion: {
print("completion block")
print("Amount: \(self.tField.text)") // Error here
})
//// other logic for app
}
tField is a local variable inside your setAmount function. It is not a property of the class.
Change:
self.tField.text
to:
tField.text
That will allow you to access the local variable.
But the real question is why are you creating a local variable of UITextField inside this function? Why are you printing its text when the text field isn't used anywhere?
Most likely you should be accessing the alert's text field inside the action handler for the "Done" button. There's no need to do anything inside the completion block of presenting the alert.
#IBAction func setAmount(_ sender: Any) {
let alert = UIAlertController(title: "Set price of service", message: "", preferredStyle: .alert)
alert.addTextField(configurationHandler: { (textField) in
print("generating textField")
textField.placeholder = "Enter amount"
})
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { (action) in
print("Cancelled")
})
alert.addAction(UIAlertAction(title: "Done", style: .default) { (action) in
print("Done !!")
if let textField = alert.textFields?.first {
print("Amount: \(textField.text)")
}
})
self.present(alert, animated: true, completion: nil)
}
My guess is that when you present an alert your current ViewController is the alert viewController... And in your alert there is no variable tField.
On the exampled you quoted the alert was presented only after the print with tField's value. That why that worked there and doesn't work in your case.
Related
I've few buttons, clicking on these buttons present same alert. I've to handle each button click separately so I need to pass different handlers to each of these alerts. How do I do it?
I've searched for solutions but I can't find what I'm looking for, or may be It's there but I'm not able to understand it.
Following is my code snippet. Inside this function I can get which button is clicked but I'm not able to figure out how to call different handlers and pass them alert.title.
I hope someone can point me in right direction.
#IBAction func buttonClicked(_ sender: UIButton) {
let alert = UIAlertController(title: "Select Value", message: nil, preferredStyle: .actionSheet)
for list in self.listValue {
alert.addAction(UIAlertAction(title: list.value, style: .default, handler: { _ in
// How do I call different handlers here?
// I'll need to retrieve alert.title in these handlers
}))
}
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil))
self.present(alert, animated: false, completion: nil)
}
It's not totally clear what you're asking, but if you are trying to figure out which button was pressed so that you can execute different methods for each one you can do something like this:
#IBAction func buttonClicked(_ sender: UIButton) {
let alert = UIAlertController(title: "Select Value", message: nil, preferredStyle: .actionSheet)
for list in self.listValue {
alert.addAction(UIAlertAction(title: list.value, style: .default, handler: { (action) in
// How do I call different handlers here?
// I'll need to retrieve alert.title in these handlers
switch action.title {
case "Value A":
print("It's Value A")
case "Value B":
print("It's Value B")
default:
print("We didn't implement anything for this value")
}
}))
}
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel, handler: nil))
self.present(alert, animated: false, completion: nil)
}
I'm trying to make an app where if the score is 3 the app displays a message that says "you lose" but keeps '3' as the number in the score label until the End Game option in the popup is pressed, at which point the score goes back to 0 for a new game. I am new to swift and am having difficulty and would really appreciate any and all help! I am not sure if making an IBAction for the alert action is the right thing to do or not.
else if rightscorecount == 3 {
let alert = UIAlertController(title: "Game", message: "You Lose!", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "End Game", style: UIAlertActionStyle.default) { UIAlertAction in})
self.present(alert, animated: true, completion: nil)
}
}
#IBAction func test(sender: UIAlertAction) {
rightscorecount = 0
rightscorelabel.text = String(rightscorecount)
}
Try this:
let alertController = UIAlertController.init(title: "Game", message: "You Lose!", preferredStyle: .alert)
alertController.addAction(UIAlertAction.init(title: "End Game", style: .default, handler: { (action) in
// Your handler goes here
self.someFunction()
}))
self.present(alertController, animated: true) {
// Completion block
}
And your function
func someFunction() {
// Function body goes here
}
I have written code for an alert to appear when the input in one of my UITextFields is less than 1050. It successfully appears when the inputs satisfies that, but after I press "OK" it instantly re-appears.
Below is the code in the viewDidLoad function:
override func viewDidLoad(){
super.viewDidLoad()
alert = UIAlertController(title: "Error", message: "Please enter an exit width value greater than 1050", preferredStyle: UIAlertControllerStyle.Alert)
let okay = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: valueCalc)
alert.addAction(okay)
}
Then I have in my valueCalc function (which is called when a button is tapped):
#IBAction func valueCalc(sender: AnyObject){
if(Int(mmText.text!)! < 1050){ //mmText is an UITextField
self.presentViewController(alert, animated: true, completion: nil)
}
}
According to your line of code
let okay = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: valueCalc)
Your handler name valueCalc is called when you press OK.
Again the value is calculated which when come out be less then the specified characters shows back you the alert.
Instead of that, replace this line in your code -
let okay = UIAlertAction(title: "OK", style: UIAlertActionStyle.Destructive, handler: handlerMethod)
and add this method to your code
func handlerMethod() {
//handle your action here after ok is pressed for e.g if you wanna just dismiss the alert then write
dismissViewControllerAnimated(true, completion: nil)
}
You have the handler argument for your UIAlertAction set to valueCalc. Therefore, whenever the user taps "OK", the method valueCalc gets run again, and since the value is (presumably) still the same, the alert is presented right back again.
Try this
override func viewDidLoad(){
super.viewDidLoad()
alert = UIAlertController(title: "Error", message: "Please enter an exit width value greater than 1050", preferredStyle: UIAlertControllerStyle.Alert)
let okay = UIAlertAction(
title: "OK",
style: UIAlertActionStyle.Destructive) { (action) in }
}
#IBAction func valueCalc(sender: AnyObject){
if(Int(mmText.text!)! < 1050){ //mmText is an UITextField
self.presentViewController(alert, animated: true, completion: nil)
}
Using iOS9 and Swift to test this UIAlertViewController. So far I am able to get the popup for the user to enter the text("Email address"). In fact I have the entered text by the user as well. but the the text displays: Optional("test#test.com"). I apologies in advance but I am rookie at the moment. Thank you so much in advance for the hints.
#IBAction func UserForgotPasswordAction(sender: AnyObject) {
func handleCancel(alertView: UIAlertAction!)
{
print("Cancelled !!")
}
let alert = UIAlertController(title: "Enter your Email Address", message: "", preferredStyle: UIAlertControllerStyle.Alert)
UIAlertViewStyle.PlainTextInput
alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in
print("generating the TextField")
textField.placeholder = "Email address"
textField.textAlignment = NSTextAlignment.Center
print("THE Input 01: \(textField.text)")
})
self.presentViewController(alert, animated: true, completion: {
print("completion block")
})
alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler:handleCancel))
alert.addAction(UIAlertAction(title: "Reset", style: UIAlertActionStyle.Default, handler:{ (UIAlertAction)in
if let textField2 = alert.textFields!.first {
print("THE Input: \(textField2.text)")
PFUser.requestPasswordResetForEmailInBackground("\(textField2.text)")
}
}))
}
Change the code inside action by adding ! as its optional:
if let textField2 = alert.textFields!.first {
print("THE Input: \(textField2.text!)")
PFUser.requestPasswordResetForEmailInBackground("\(textField2.text!)")
}
In my application I want a alert with a textfield. After clicking on "Done" I want to save the textfield input in a String. After clicking on "Cancel" I want only to close the alert. I've created my alert like this:
var alert = UIAlertView()
alert.title = "Enter Input"
alert.addButtonWithTitle("Done")
alert.alertViewStyle = UIAlertViewStyle.PlainTextInput
alert.addButtonWithTitle("Cancel")
alert.show()
let textField = alert.textFieldAtIndex(0)
textField!.placeholder = "Enter an Item"
println(textField!.text)
The alert looks like this:
I want to know how to get the text from the textfield, and how to create events for the "Done" button and the "Cancel" button.
You may go with UIAlertController instead of UIAlertView.
I've already implemented and tested too using UIAlertController for what you actually want. Please try the following code
var tField: UITextField!
func configurationTextField(textField: UITextField!)
{
print("generating the TextField")
textField.placeholder = "Enter an item"
tField = textField
}
func handleCancel(alertView: UIAlertAction!)
{
print("Cancelled !!")
}
var alert = UIAlertController(title: "Enter Input", message: "", preferredStyle: .Alert)
alert.addTextFieldWithConfigurationHandler(configurationTextField)
alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler:handleCancel))
alert.addAction(UIAlertAction(title: "Done", style: .Default, handler:{ (UIAlertAction) in
print("Done !!")
print("Item : \(self.tField.text)")
}))
self.presentViewController(alert, animated: true, completion: {
print("completion block")
})
You will have to implement the UIAlertViewDelegate's
optional func alertView(_ alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int)
For SWIFT 3
#IBAction func ForgotPassword(_ sender: Any) {
let alertController = UIAlertController(title: "Email?", message: "Please input your email:", preferredStyle: .alert)
let confirmAction = UIAlertAction(title: "Confirm", style: .default) { (_) in
if let field = alertController.textFields![0] as? UITextField {
// store and use entered data
} else {
print("please enter email id")
}
}
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)
}
I hope it will help someone else :)
For iOS 8+ you should use UIAlertController instead of UIAlertView. To support iOS 7 you should implement (UIAlertViewDelegate):
func alertView(alertView: UIAlertView, clickedButtonAtIndex buttonIndex: Int)
{
//...
let textField = alertView.textFieldAtIndex(0)
}