UIButton can't be touched while animated with UIView animateWithDuration

Shai Mishali picture Shai Mishali · Dec 1, 2011 · Viewed 20.6k times · Source

I have the following code:

[UIView animateWithDuration:0.3
                      delay:0.0
                    options:UIViewAnimationCurveEaseOut | UIViewAnimationOptionAllowUserInteraction
                 animations:^{
                     CGRect r = [btn frame];
                     r.origin.y -= 40;
                     [btn setFrame: r];
                 }
                 completion:^(BOOL done){
                     if(done){
                         [UIView animateWithDuration:0.3
                                               delay:1
                                             options:UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionAllowUserInteraction
                                          animations:^{
                                              CGRect r = [btn frame];
                                              r.origin.y += 40;
                                              [btn setFrame: r];
                                          }
                                          completion:^(BOOL done){if(done) zombiePopping = 0; }];
                     }

                 }];

The problem is, it seems the button doesnt respond to touches while being animated even though i'm using UIViewAnimationOptionAllowInteraction, which is a bit weird to me.

Maybe this most be done with Core Animation to work? and if so, how would i go about that?

Answer

nahung89 picture nahung89 · Jun 28, 2015

Swift 5

In my case, when I set button.alpha = 0, the button interaction stops working, no matter if I setup UIViewAnimationOptionAllowUserInteraction as an option.

Reason

Whenever you define the animation or not, the view's property is applying to view's layer immediately. Because of this, when you set the view.alpha=0, you hide the view completely.

Solution

Easy, just reduce alpha=0.1 (or even 0.05)

UIView.animate(withDuration: 2,
                       delay: 0,
                       options: [.allowUserInteraction, .overrideInheritedOptions, .curveEaseOut, .repeat, .autoreverse],
                       animations: {
                           self.button.layer.opacity = 0.01 // 0.0 will make the button unavailable to touch
        })