2017-04-27 109 views
1

我在Swift 3项目的UIImageView项目上使用自定义路径动画。代码大纲如下:在动画UIImageView上检测水龙头

// 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时间,之前的手势识别被覆盖,所以任何检测到的tap总是指向LAST添加的图像,并且该位置未被准确检测到(所以如果有人在父视图上的任何地方点击,它仍会触发onTap方法)。

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

+0

我实现了你的子类,但有时它不起作用:按钮没有注意到它被点击,但有时它确实看到它。这是我的问题:https://stackoverflow.com/questions/46391003/retrieve-tapped-uibutton-in-a-moving-uibezierpath –

回答

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的tap检测,因此如果您可以举一个例子来说明如何使用UIViewPropertyAnimator来完成上述操作,我会将您的答案标记为正确的。

1

你不是很清楚你想达到什么,但我认为你应该添加手势识别器到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))") 
+0

我试过,最初,没有运气。另外,作为一个实验,我将UIImageView分类并尝试在其中添加手势识别器,但在图像上从未检测到水龙头。尽管将isUserInteractionEnabled设置为true。 – LNI

+0

如果您完全删除动画,请点按工作?就在一个静态的UIImageViews上。 –

+0

是的,它的确如此 - 问题在于当图层动画时,它们的“位置”不会更新。 – LNI

0

我想你可以检查属于imageView的水龙头位置或不在onTap func灰。 像这样:

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

不起作用。查看我发布的答案。 – LNI