scooby scooby - 10 days ago 5
Swift Question

Problems updating countdown timer in UIAlertController

I'm trying to update a countdown timer in the message part of a UIAlertController. I've tried lots of answers suggested on here but with no joy.
I have a simple ViewController to try out what I'm trying to achieve.

class ViewController: UIViewController {

var counter:Int = 5
var timer: NSTimer?
var label = ""
var message = "in "

override func viewDidLoad() {
super.viewDidLoad()
}

override func viewDidAppear(animated: Bool) {
showAlert()
}

func showAlert(){
let alertController = UIAlertController(title: "Try again ", message: countDownString(), preferredStyle: .Alert)

presentViewController(alertController, animated: true){
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(self.decrease), userInfo: nil, repeats: true)
}
}

func decrease()
{
var minutes: Int
var seconds: Int
if(counter > 0) {
self.counter -= 1
print(counter) // Correct value in console
minutes = (counter % 3600) / 60
seconds = (counter % 3600) % 60
label = String(format: "%02d:%02d", minutes, seconds)
print(label) // Correct value in console
}
else{
dismissViewControllerAnimated(true, completion: nil)
timer!.invalidate()
}
}

func alertMessage() -> String {
print(message+"\(self.label)")
return(message+"\(self.label)")
}

func countDownString() -> String {
print("\(counter) seconds")
return "\(counter) seconds"
}


}

Counter and Label both show the correct values in the console but I'm unable to get them to display the values in the UIAlertController.
screenshots show the output i'm getting in the view controller.

Where am I going wrong?

alertMessage screenshot
countDownString screenshot

I'm using Xcode 7.3 and Swift 2.2

Answer

When you instantiate your UIAlertController in the code below, current value from countDownString() is copied as message and cannot be updated this way

let alertController = UIAlertController(title: "Try again ", message: countDownString(), preferredStyle: .Alert)

You should store your UIAlertController as instance property, something like this:

var alertController: UIAlertController!

change your code for showAlert() to:

func showAlert(){
    alertController = UIAlertController(title: "Try again ", message: countDownString(), preferredStyle: .Alert)
    presentViewController(alertController, animated: true){
        self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(self.decrease), userInfo: nil, repeats: true)
    }
}

and update alertController message directly in your decrease() function:

func decrease()
{
    var minutes: Int
    var seconds: Int
    if(counter > 0) {
        self.counter -= 1
        print(counter)  // Correct value in console
        minutes = (counter % 3600) / 60
        seconds = (counter % 3600) % 60
        alertController.message = String(format: "%02d:%02d", minutes, seconds)
        print("\(minutes):\(seconds)")  // Correct value in console
    }
    else{
        dismissViewControllerAnimated(true, completion: nil)
        timer!.invalidate()
    }
}
Comments