使用UIView animateWithDurationanimation时,不能触摸UIButton

我有以下代码:

[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; }]; } }]; 

问题是,似乎button没有响应触摸animation时,即使我使用UIViewAnimationOptionAllowInteraction ,这是UIViewAnimationOptionAllowInteraction我。

也许这最核心的animation工作? 如果是的话,我将如何去呢?

8 Solutions collect form web for “使用UIView animateWithDurationanimation时,不能触摸UIButton”

animation时,button的可触摸部分与button的可见框不一致。

在内部,button的框架将被设置为animation的最终值。 你应该发现,你可以在这个领域挖掘,它会工作。

要打一个移动的button,你需要对button的.layer.presentationLayer属性进行testing(需要导入QuartzCore框架来完成)。 这通常会在视图控制器中的触摸处理方法中完成。

如果您需要更多,我很乐意扩大这个答案。

这里是如何通过命中testing表示层来响应触摸事件。 此代码位于正在pipe理button的视图控制器子类中。 当我这样做时,我对初始触摸感兴趣,而不是触摸结束(这通常是一个水龙头会注册的),但原理是一样的。

记得导入QuartzCore框架并将其添加到您的项目。

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint touchLocation = [touch locationInView:self.view]; for (UIButton *button in self.buttonsOutletCollection) { if ([button.layer.presentationLayer hitTest:touchLocation]) { // This button was hit whilst moving - do something with it here break; } } } 

在我的情况下,我设置superView.alpha = 0,它停止button的交互,虽然我设置UIViewAnimationOptionAllowUserInteraction

解? 简单,只需将alpha减less到0.1而不是0

 [UIView animateWithDuration:durationTime delay:0 options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionOverrideInheritedOptions | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAutoreverse animations: ^{ superView.alpha = 0.1; // 0.0 will make the button unavailable to touch } completion:nil]; 

选项的顺序很重要,您必须首先放置UIViewAnimationOptionAllowUserInteraction ,然后添加其他选项。

在Swift 3中使用: .allowUserInteraction

我已经使用NSTimer实现了这个function:首先,执行启动animation,然后启动一个计时器,这是演示代码:

 -(void)fun··· { [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){}]; then , you should start an timer,example: //start timer if (timer != nil) { [timer invalidate]; timer = nil; } [self performSelector:@selector(closeButton) withObject:nil afterDelay:0]; } - (void)closeButton { if (timer != nil) { return; } //start timer timer = [NSTimer scheduledTimerWithTimeInterval:1.5f target:self selector:@selector(timerEvent) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; } - (void)timerEvent { [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; }]; [timer invalidate]; timer = nil; } 

在Swift(2.0)中的相同答案,为懒惰。 如有必要,请用循环和sockets集合replace:

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { let touch = touches.first let touchLocation = touch!.locationInView(self.view) if self.button.layer.presentationLayer()!.hitTest(touchLocation) != nil { action() // Your action, preferably the original button action. } } 

Swift版本: '999'是用于标识目标视图的标签值。

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { let touch = touches.first let touchLocation = (touch?.locationInView(self.rootView))! for view in self.view.subviews { if let layer = view.layer.presentationLayer()?.hitTest(touchLocation) where view.tag == 999 { // Here view is the tapped view print(view) } } } 

奇迹般有效

override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { if bounds.contains(point) && !hidden && userInteractionEnabled && enabled { return self } return super.hitTest(point, withEvent: event) }

虽然这个答案也是正确的

Swift 3.0在viewdidload顶部创build一个超级视图

 let superView = UIView(frame: view.frame) superView.isUserInteractionEnabled = true superView.backgroundColor = UIColor.clear superView.alpha = 0.1 view.addSubview(superView) 

现在就这样实行touchesbagan

 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = (touches as NSSet).anyObject() as? UITouch else { return } let touchLocation = touch.location(in: self.view) if btnone.layer.presentation()?.hitTest(touchLocation) != nil { print("1") // Do stuff for button } if btntwo.layer.presentation()?.hitTest(touchLocation) != nil { print("2") // Do stuff } if btnthree.layer.presentation()?.hitTest(touchLocation) != nil { print(3) // Do stuff } if btnfour.layer.presentation()?.hitTest(touchLocation) != nil { print(4) // Do stuff } }