如果按照常规方法去写这个过程,代码如下:
@interface ViewController ()
@property (nonatomic, strong) UIButton * button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
self.button.backgroundColor = [UIColor redColor];
[self.button addTarget:self action:@selector(btnClicked) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.button];
//设置动画匀速并且在运动期间打开用户交互
[UIView animateWithDuration:10.f
delay:0
options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction
animations:^{
self.button.frame = CGRectMake(0, 400, 100, 100);
} completion:^(BOOL finished) {
}];
}
- (void)btnClicked{
NSLog(@"button clicked");
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
会发现在动画还没有运行到目标位置的时候,直接点击目标位置也会响应点击事件。
更改代码如下:通过对比点击位置与动画当前坐标的方法来准确响应点击事件
@interface ViewController ()
@property (nonatomic, strong) UIButton * button;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
self.button.backgroundColor = [UIColor redColor];
// 关闭按钮的用户交互,使得点击事件穿透按钮,到达self.view
self.button.userInteractionEnabled = NO;
[self.view addSubview:self.button];
//设置动画匀速并且在运动期间打开用户交互
[UIView animateWithDuration:10.f delay:0 options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction animations:^{
self.button.frame = CGRectMake(0, 400, 100, 100);
} completion:^(BOOL finished) {
}];
}
//点击事件
- (void)btnClicked{
NSLog(@"button clicked");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//获取点击点坐标
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
//获取动画当前中心点坐标
CGPoint currentPosition = [[self.button.layer presentationLayer] position];
if (touchPoint.x > currentPosition.x - 50 && touchPoint.x < currentPosition.x + 50 && touchPoint.y > currentPosition.y - 50 && touchPoint.y < currentPosition.y + 50) {
[self btnClicked];
}
}
更改后,移动中的button就可以正常识别点击事件了