so the way my app works is you tap on a cell , a var value gets modified (+1 for example). I've figured out how to get a UIalert to pop when my var reaches a certain value (10). But now everytime I update the var the alert pops. What i would like it to do is to pop when the var hits 10 and stop after that
Heres the code :
if (section1score >= 10){
let alertController: UIAlertController = UIAlertController(title: NSLocalizedString("Section 1 score is over 10", comment: ""),
message: " \(message1)",
preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default) {
action -> Void in }
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
if (section2score >= 10){
let alertController: UIAlertController = UIAlertController(title: NSLocalizedString("Section 2 Score is over 10", comment: ""),
message: "\(message2)",
preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default) {
action -> Void in }
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
Setup a Bool to check if the alert has been shown or not. Create the Bool globally and set it to false initially.
var showedAlert = false
func yourFunction() {
if section1score >= 10 && showedAlert == false {
// show alert
showedAlert = true
}
if section2score >= 10 && showedAlert == false {
// show alert
showedAlert = true
}
}
Comparison Operators
You could use a property to keep track of when you show the alert so that once you show it, you won't show it again.
var hasShownAlert: Bool = false
if (section1score >= 10 && !hasShownAlert){
let alertController: UIAlertController = UIAlertController(title: NSLocalizedString("Section 1 score is over 10", comment: ""),
message: " \(message1)",
preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default) {
action -> Void in }
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true, completion: nil)
hasShownAlert = true
}
if (section2score >= 10 && !hasShownAlert){
let alertController: UIAlertController = UIAlertController(title: NSLocalizedString("Section 2 Score is over 10", comment: ""),
message: "\(message2)",
preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default) {
action -> Void in }
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true, completion: nil)
hasShownAlert = true
}
Related
Inside textViewDidBeginEditing I'm showing alert using UIAlertController. Alert is shown prior to the keyboard (on simulator).
How do I show keyboard before alert pops up?
func textViewDidBeginEditing(_ textView: UITextView) {
if self.balance <= 0 {
let alert = UIAlertController(title: "Balance Low", message: "Your balance is low.", preferredStyle: UIAlertControllerStyle.alert)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel) { (cancel) in
}
let okAction = UIAlertAction(title: "Buy", style: UIAlertActionStyle.default) { (action) in
self.segueToBuy()
}
alert.addAction(cancelAction)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
Please use DispatchQueue.main.asyncAfter to show the alert after certain delay, whenever user typed the text in UITextView.
func asyncAfter(deadline: DispatchTime, qos: DispatchQoS = default, flags: DispatchWorkItemFlags = default, execute work: #escaping #convention(block) () -> Void)
Delcare private instance variable which is used to show alert, locally.
var showAlert = true
Try the code shown below in textViewDidBeginEditing:
func textViewDidBeginEditing(_ textView: UITextView) {
if self.showAlert && self.balance <= 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
textView.endEditing(true)
let alert = UIAlertController(title: "Balance Low", message: "Your balance is low.", preferredStyle: UIAlertController.Style.alert)
let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel) { (cancel) in
self.showAlert = false
textView.becomeFirstResponder()
}
let okAction = UIAlertAction(title: "Buy", style: UIAlertAction.Style.default) { (action) in
textView.endEditing(true)
self.segueToBuy()
}
alert.addAction(cancelAction)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
}
What I am trying to do is that I am taking user's contact number (mobile number) if it is correct then it should continue the signup otherwise the alert controller should not hide and show some error
let alertController = UIAlertController(title: "Phone Number", message: "Please enter your number", preferredStyle: .alert)
alertController.addTextField {
(textField) -> Void in
textField.tag = 128
textField.delegate = self
textField.placeholder = "923xxxxxxxxx"
}
alertController.addAction(UIAlertAction(title: "Continue", style: .default, handler: {
alert -> Void in
let textField = alertController.textFields![0] as UITextField
if (textField.text?.count)! == 12 && ((textField.text?.substring(to: 3))!) == "923" {
//my code
}
else {
//should show/keep alert controler
}
}))
self.present(alertController, animated: true, completion: nil)
Try out this,
let alertController = UIAlertController(title: "Phone Number", message: "Please enter your number", preferredStyle: .alert)
alertController.addTextField {
(textField) -> Void in
textField.tag = 128
textField.delegate = self
textField.placeholder = "923xxxxxxxxx"
}
alertController.addAction(UIAlertAction(title: "Continue", style: .default, handler: {
alert -> Void in
let textField = alertController.textFields![0] as UITextField
if (textField.text?.count)! == 12 && ((textField.text?.substring(to: 3))!) == "923"
{
//my code
}
else
{
//alert with error
let alertControllerError = UIAlertController(title: "error", message: "error here", preferredStyle: .alert)
alertControllerError.addAction(UIAlertAction(title: "ok", style: .default, handler: { alert -> Void in
}))
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(1)) {
self.present(alertControllerError, animated: true, completion: nil)
}
}
}))
self.present(alertController, animated: true, completion: nil)
You could disable the button (UIAlertAction) by default. Then listen to text changes in your UITextField and update the button accordingly:
var autoEnableAlertAction: UIAlertAction?
func presentAlertController() {
// alert controller
let ac = UIAlertController(title: "Registration", message: "Please enter your phone number.", preferredStyle: .Alert)
// alert action - disabled by default
let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
okAction.enabled = false
ac.addAction(okAction)
// store a reference to the alert action to enable / disable it later
autoEnableAlertAction = okAction
ac.addTextFieldWithConfigurationHandler { tf in
// listen for changes in the textfield
tf.addTarget(self, action: #selector(self.checkTextFieldText(_:)), forControlEvents: .EditingChanged)
}
presentViewController(ac, animated: true, completion: nil)
}
#objc func checkTextFieldText(textField: UITextField) {
autoEnableAlertAction?.enabled = textField.text?.characters.count >= 5
}
Sorry for my answer being a Swift 2 version... :)
func presentAlertController()
{
let alertController = UIAlertController(title: "Phone Number", message: "Please enter your number", preferredStyle: .alert)
alertController.addTextField {
(textField) -> Void in
textField.tag = 128
textField.placeholder = "923xxxxxxxxx"
}
alertController.addAction(UIAlertAction(title: "Continue", style: .default, handler: {
alert -> Void in
let textField = alertController.textFields![0] as UITextField
if (textField.text?.count)! == 12 && textField.text?.prefix(3) == "923"
{
print("sucess")
}
else
{
print("Incorrect Number")
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(2)) {
self.presentAlertController(parameters: parameters)
}
}
}))
alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler:{
alert -> Void in
}))
self.present(alertController, animated: true, completion: nil)
}
I have some code in my project:
#IBAction func createAccountAction(sender: AnyObject) {
if self.emailField.text == "" || self.passwordField.text == ""
{
let alertController = UIAlertController(title: "Oops!", message: "Please enter an email and password.", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
else
{
FIRAuth.auth()?.createUserWithEmail(self.emailField.text!, password: self.passwordField.text!) { (user, error) in
if error == nil
{
let alertController = UIAlertController(title: "Done", message: "Account created!", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.emailField.text = ""
self.passwordField.text = ""
}
else
{
let alertController = UIAlertController(title: "Oops!", message: error?.localizedDescription, preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
As you can see in the last else statement I have a alertController with the message Oops that will show when clicking the createAccountAction button.
But that happens when the user presses the button and has not filled in anything in the textfields.
Now what I want is that when a user succesfully fills in the textfields, that a same popup should appear along with other text that I specified.
When I run the code it does the part
self.emailField.text = ""
self.passwordField.text = ""
but does not present the AlertController.
How can I achieve what I want?
You're missing the line:
self.presentViewController(alertController, animated: true, completion: nil)
which should be after:
self.emailField.text = ""
self.passwordField.text = ""
So you aren't presenting the alert.
Also. You can change that entire function to this much simpler one:
#IBAction func createAccountAction(sender: AnyObject) {
if self.emailField.text == "" || self.passwordField.text == "" {
let title = "Oops"
let message = "Please enter an email and password."
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
} else {
FIRAuth.auth()?.createUserWithEmail(self.emailField.text!, password: self.passwordField.text!) { (user, error) in
var title : String
var message : String
if error == nil {
title = "Done"
message = "Account created!"
self.emailField.text = ""
self.passwordField.text = ""
} else {
title = "Oops!"
message = "error?.localizedDescription"
}
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
}
You are only presenting the alert controller in the 'else' part of your 'if else' statement.
Additionally refactored example to ensure bugs like that don't happen:
var title: String!
var message: String!
if let error = error {
title = "Oops!"
message = error.localizedDescription
} else {
title = "Done"
message = "Account created!"
self.emailField.text = ""
self.passwordField.text = ""
}
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alertController.addAction(defaultAction)
self.presentViewController(alertController, animated: true, completion: nil)
I want to have a UIAlertViewController that presents some text, and when you click "ok" it causes another UIAlertController to pop up and it will present the user with two options to choose from (go to main, restart game). this is the code I wrote and it brings up this error:
"2015-11-16 22:29:21.438 MemoryCardGameTest_01[1917:46708] Warning:
Attempt to present on
which is already
presenting (null)"
func showWinMessage() {
let userMessage = UIAlertController(title: "Victory! you win with... clicks \(ref2.clickCounter) and \(ref2.timeCounter) seconds", message: "", preferredStyle: UIAlertControllerStyle.Alert);
let action = UIAlertAction(title: "ok", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in
}
userMessage.addAction(action);
self.presentViewController(userMessage, animated: true, completion: nil);
println("victory achieved");
}
func showUserMessage(){
let newMessage = UIAlertController(title: "whatwouldyouliketodonext?", message: "", preferredStyle: UIAlertControllerStyle.Alert);
let goToUI = UIAlertAction(title: "goToUI", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in
println("gotoUI was clicked");
}
let playAgain = UIAlertAction(title: "PlayAgain", style: UIAlertActionStyle.Default) { (action: UIAlertAction!) -> Void in
println("playAgain was clicked");
}
newMessage.addAction(goToUI);
newMessage.addAction(playAgain);
self.presentViewController(newMessage, animated: true, completion: nil);
}
This roughly does what you want. Just make sure you don't call it in viewDidLoad as you can get an error like you mentioned. Try viewDidAppear or something.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let alertController = UIAlertController(title: "First message", message: "This is the first message", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
let alertController = UIAlertController(title: "Second message", message: "This is the second message", preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
// ...
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) {
// ...
}
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true) {
// ...
}
}
Essentially I just set the second view to appear in OKAction of the first alertController.
I'd like to get an alert to show when 3 specific value is reached,
here's my code
func SectionAlert () {
if (section1score >= 10){
let alertController: UIAlertController = UIAlertController(title: "Alert", message: "\((section1score as NSNumber).stringValue)", preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default) {
action -> Void in
}
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true, completion: nil)
} else if (section2score >= 10){
} else if (section3score >= 10){
}
}
My App updates each sections value when a cell is tapped in the TableView
My code does not show any error but it does not give me my alert when my value reaches 10 and over
any ideas??
thanks !