I tested it. When I moved the View, the tap event on the view doesn't respond, and it only responded when it stopped. I don't know why this happens. Below is my code
@interface ViewController ()
@property(nonatomic,strong)UIView *testView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.testView = [[UIView alloc]init];
self.testView.backgroundColor = [UIColor redColor];
self.testView.frame = CGRectMake(0, 100, 100, 100);
[self.view addSubview:self.testView];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapTestView:)];
[self.testView addGestureRecognizer:tap];
}
- (void)tapTestView:(UITapGestureRecognizer *)tap {
NSLog(@"Event triggered");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[UIView animateWithDuration:6 animations:^{
CGRect frame = self.testView.frame;
frame.origin.x = 400;
self.testView.frame = frame;
}];
}
First, you want to make sure to use
animatewithduration:delay:options:animations:completion:with theUIViewAnimationOptionAllowUserInteractionoption. If you do not use this option, animated views will not receive touches.Second, when views are animated, if you examine the
frameof that view as it is moving, you will see that theframeproperty won’t reflect where the view really is at that moment of time, but, rather, where it will eventually be. Specifically, theframeproperty will be that value you set in thatanimationsblock, even if it hasn’t finished actually moving there, yet.The implication of this behavior is that, even if you enable user interaction during animation, as shown above, gestures will be recognized based upon the view’s final destination rather than where it is now. E.g., if you start animation of frame from rect A to rect B, the gesture recognizer will recognize taps within rect B even if the view is not there yet! And conversely, it won’t recognize taps where the animated view happens to be, because the
frameeffectively thinks the view is already at the destination.To get around that issue, one must refer to the view’s layer’s
presentationLayerto get the location of the view mid-animation. One approach is to add a gesture recognizer to the main view and then, in there, see if the touch was inside the animated view’s presentation layer:Alternatively, you can (a) define a
UIViewsubclass for the child view and (b) override itshitTestimplementation to factor in the presentation layer: