UIButton not interacting during animation

2019-01-27 18:32发布

I'm trying to animate a UIButton. But during it's animation, there is no interaction with the UIButton. Expected behavior is to be able to click on the button while it's moving. Here's the code snippet of the UIButton and animation:

UIImage *cloudImage = [UIImage imageNamed:@"sprite.png"];    
UIButton moveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[moveBtn setFrame:CGRectMake(0.0, 80.0, cloudImage.size.width, cloudImage.size.height)];
[moveBtn setImage:cloudImage forState:UIControlStateNormal];
[moveBtn addTarget:self action:@selector(hit:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:moveBtn];
CGPoint newLeftCenter = CGPointMake( 300.0f + moveBtn.frame.size.width / 2.0f, moveBtn.center.y);
[UIView beginAnimations:nil context:nil]; 
[UIView setAnimationDuration:5.0f];
[UIView setAnimationRepeatCount:HUGE_VALF];
moveBtn.center = newLeftCenter;
[UIView commitAnimations];

hit selector just displays an NSLog to show if the button respond to it or not. Any help would be appreciated.

5条回答
一夜七次
2楼-- · 2019-01-27 19:09

Try setting the animation option to UIViewAnimationOptionAllowUserInteraction.

[UIView animateWithDuration:.2
                      delay: 0
                    options: UIViewAnimationOptionAllowUserInteraction
                 animations:^{ 
                     // animation logic
                 }
                 completion:^(BOOL completed) { 
                     // completion logic
                 }
 ];
查看更多
来,给爷笑一个
3楼-- · 2019-01-27 19:10

Another option is to add a transparent button over the button you are animating. In your particular case you might not be able to use this, as you are moving the button, but you might be able to create an overlay button big enough to cover from the start position to the final one.

I had this problem, and in my case using UIViewAnimationOptionAllowUserInteraction didn't work. I was animating the alpha of a UIButton inside a UIBarButtonItem (created with initWithCustomView:) to make a pulsating effect, and that option wouldn't work. I don't like the NSTimer option either (not smooth), so in the end I just added an overlay button, which I don't like, but works flawlessly.

查看更多
女痞
4楼-- · 2019-01-27 19:12

This problem is caused by large animations per block. I made an NSTimer based solution, like the one suggested above, and it worked... yet the movement was jerky (unless I inserted animation within every timer event trigger).

So, since animation was required anyway, I found a solution which requires no timer. It animates only a short distance and thus the button click is still accurate, with only a small error which is my case is very unnoticeable in the UI, and can be reduced depending on your params.

Note below that the error at any given time is < 15.0, which can be reduced for more accuracy depending on your animation speed requirements. You can also reduce the duration time for more speed.

- (void)conveyComplete:(UIView*)v
{
    [self convey:v delay:0];
}

- (void)convey:(UIView*)v delay:(int)nDelay
{
    [UIView animateWithDuration:.5 
                          delay:nDelay
                        options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)  
                     animations: ^
                    {
                        CGRect rPos = v.frame; 
                        rPos.origin.x -= 15.0;
                        v.frame = rPos;
                    }
                    completion: ^(BOOL finished)
                    {
                        [self conveyComplete:v];
                    }];

}
查看更多
Summer. ? 凉城
5楼-- · 2019-01-27 19:19

For swift 4 this code works,

UIView.animate(withDuration: 2, delay: 0, options: [.autoreverse, .repeat, .allowUserInteraction],
                   animations: {
                    self.btnCashGame?.frame.origin.y -= 15



    },completion:  { (finished: Bool) in
        self.btnCashGame?.frame.origin.y += 15

    })
查看更多
Viruses.
6楼-- · 2019-01-27 19:29

There were some questions here recently about this. The animation is purely visual. You can tap the button in it'd old frame until the animation is complete, when it finishes, the actual button jumps.

EDIT:

This answer is what I was referring to. You need to manually move the button with an NSTimer, apparently. See the linked question/answer for more.

Other folks suggest passing UIViewAnimationOptionAllowUserInteraction as a UIViewAnimation option.

查看更多
登录 后发表回答