动画时点按UIImage

时间:2019-07-15 00:45:05

标签: ios swift uiviewanimation uitapgesturerecognizer

我一直试图在动画到屏幕顶部和print("Image Tapped")时点按UIImage,但没有成功。

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")
}

1 个答案:

答案 0 :(得分:2)

问题在于,图像视图不在动画过程中看到的位置(它位于动画的端点)。因此,您无需在图像视图上点击它的位置,因此不会检测到点击。

因此,您必须对表示层进行命中测试,或者,如果不想这样做,则必须使用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()