我一直在尝试能够点击UIImage,因为它的动画到我的屏幕顶部并print("Image Tapped")
,但没有成功。
override func viewDidLoad() {
super.viewDidLoad()
redBalloon.image = UIImage(named: "redBalloon")
redBalloon.contentMode = .scaleAspectFit
redBalloon.frame = CGRect(x: Int(xOrigin), y: 667, width: Int(redBalloon.frame.size.width), height: Int(redBalloon.frame.size.height))
UIView.animate(withDuration: 5, delay: 0, options: UIImageView.AnimationOptions.allowUserInteraction, animations: {
self.redBalloon.frame = CGRect(x: Int(self.xEnding), y: -192, width: 166, height: 192)
}, completion: {(finished:Bool) in
self.endGame()
})
let imageTap = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
redBalloon.isUserInteractionEnabled = true
redBalloon.addGestureRecognizer(imageTap)
}
@objc func imageTapped(_ sender: UITapGestureRecognizer) {
// do something when image tapped
print("image tapped")
}
问题是图像视图不在动画过程中看到它的位置(它位于动画的端点)。因此,您没有在图像视图所在的位置点击图像视图,因此不会检测到点击。
因此,要么必须对表示层进行命中测试,要么,如果不想这样做,则必须使用 UIViewPropertyAnimator 而不是调用UIView.animate
。
作为第一种方法的示例,我将对 UIImageView 进行子类化。使你的UIImageView成为这个子类的实例:
class TouchableImageView : UIImageView {
override func hitTest(_ point: CGPoint, with e: UIEvent?) -> UIView? {
let pres = self.layer.presentation()!
let suppt = self.convert(point, to: self.superview!)
let prespt = self.superview!.layer.convert(suppt, to: pres)
return super.hitTest(prespt, with: e)
}
}
但是,我个人认为使用UIViewPropertyAnimator要简单得多。在这种情况下,不要让你的UIImageView成为TouchableImageView!您不想进行额外的命中测试。只需让属性动画师完成所有工作:
redBalloon.image = UIImage(named: "redBalloon")
redBalloon.contentMode = .scaleAspectFit
redBalloon.frame = CGRect(x: Int(xOrigin), y: 667, width: Int(redBalloon.frame.size.width), height: Int(redBalloon.frame.size.height))
let anim = UIViewPropertyAnimator(duration: 5, timingParameters: UICubicTimingParameters(animationCurve: .easeInOut))
anim.addAnimations {
self.redBalloon.frame = CGRect(x: Int(xEnding), y: -192, width: 166, height: 192)
}
anim.addCompletion { _ in
self.endGame()
}
let imageTap = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
redBalloon.isUserInteractionEnabled = true
redBalloon.addGestureRecognizer(imageTap)
anim.startAnimation()