首页 文章

检测动画UIImageView上的点击

提问于
浏览
1

我在UIImageView项目上为Swift 3项目使用自定义路径动画 . 代码大纲如下:

// parentView and other parameters are configured externally
let imageView = UIImageView(image: image)
imageView.isUserInteractionEnabled = true
let gr = UITapGestureRecognizer(target: self, action: #selector(onTap(gesture:)))
parentView.addGestureRecognizer(gr)
parentView.addSubview(imageView)
// Then I set up animation, including:
let animation = CAKeyframeAnimation(keyPath: "position")
// .... eventually ....
imageView.layer.add(animation, forKey: nil)

onTap方法以标准方式声明:

func onTap(gesture:UITapGestureRecognizer) {
    print("ImageView frame is \(self.imageView.layer.visibleRect)")
    print("Gesture occurred at \(gesture.location(in: FloatingImageHandler.parentView))")
}

问题是,每次我调用addGestureRecognizer时,先前的手势识别器都会被覆盖,因此任何检测到的点击始终指向最后添加的图像,并且未准确检测到位置(因此,如果有人在父视图上的任何位置轻敲,它仍会触发onTap方法) .

如何在每个imageView的基础上准确检测到一个水龙头?由于自定义路径动画要求,我无法使用UIView.animate或其他方法,我也无法创建覆盖透明UIView来覆盖父视图,因为我需要这些“浮动”以不吞下事件 .

3 回答

  • 0

    目前还不是很清楚你想要实现什么,但我认为你应该将手势识别器添加到imageView而不是父视图 .

    所以这:

    parentView.addGestureRecognizer(gr)
    

    应该替换为:

    imageView.addGestureRecognizer(gr)
    

    在你的onTap函数中你可能应该这样做:

    print("ImageView frame is \(gesture.view.layer.visibleRect)")
    print("Gesture occurred at \(gesture.location(in: gesture.view))")
    
  • 1

    我想你可以在 onTap 功能上检查属于 imageView 的分接位置 . 像这样:

    func ontap(gesture:UITapGestureRecognizer) {
            let point = gesture.location(in: parentView)
            if imageView.layer.frame.contains(point) {
                print("ImageView frame is \(self.imageView.layer.visibleRect)")
                print("Gesture occurred at \(point)")
            }
        }
    
  • 0

    由于图层不更新它们的帧/位置等,我需要在我写的图像视图子类中添加以下内容( FloatingImageView ):

    override func hitTest(_ point: CGPoint, with event: 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: event)
    }
    

    我还将手势识别器移动到父视图,因此任何时候只有一个GR,并为每个要添加的子视图创建唯一标记 . 处理程序如下所示:

    func onTap(gesture:UITapGestureRecognizer) {
        let p = gesture.location(in: gesture.view)
        let v = gesture.view?.hitTest(p, with: nil)
        if let v = v as? FloatingImageView {
            print("The tapped view was \(v.tag)")
        }
    }
    

    其中 FloatingImageViewUIImageView 子类 .

    这个方法在iOS 10书籍(以及WWDC)中有所描述,也适用于iOS 9 . 我仍在评估基于 UIViewPropertyAnimator 的点击检测,所以如果你能给我一个如何使用 UIViewPropertyAnimator 来做上述事例的例子,我会将你的答案标记为正确答案 .

相关问题