meteors meteors - 1 year ago 57
iOS Question

Animation callback altering a different variable

I have a button which shows a view and which automatically goes away after specified time interval. Now if the button is pressed again while the view is already visible then it should go away and show a new view and the timer for new view be reset.

On the button press I have following code:

func showToast() {
timer = nil


var appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var toAddView = appDelegate.window!

toastView = UIView(frame: CGRectMake(0, toAddView.frame.height, toAddView.frame.width, 48))
toastView.backgroundColor = UIColor.darkGrayColor()

timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("removeToast"), userInfo: nil, repeats: false)

UIView.animateWithDuration(0.5, animations: { () -> Void in
self.toastView.frame.origin.y -= 48

To remove toast i have the following code:

func removeToast() {
if toastView != nil {
animations: { () -> Void in
self.toastView.frame.origin.y += 48
completion: {(completed: Bool) -> Void in
self.toastView = nil

Now even though I reset the timer each time by doing
I get two calls in
which removes the newly inserted view. Can it be that
be causing problems, I'm not getting how to debug the two callbacks for
. A demo project showing the behavior is here

NOTE: I did find some post saying to use
instead of timer, also as asked by @jervine10, but it does not suffice my scenario. As if I use
then it's difficult to invalidate GCD call. Is there something that could be accomplished with NSTimers. I think that NSTimers are meant for this and there's something that I'm doing wrong.

Answer Source

Use dispatch_after to call a method after a set period of time instead of a timer. It would look like this:

let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(2 * NSEC_PER_SEC))
dispatch_after(popTime, dispatch_get_main_queue()) { () -> Void in