2017-04-27 6 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を呼び出すたびに、前のジェスチャ認識が上書きされることをですので、任意の検出されたタップは常に最後に追加されたイメージを指し、その場所は正確には検出されません(したがって、誰かがparentViewをタップすると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が1つしかなく、追加される各サブビューに対して固有のタグが作成されました。

FloatingImageViewUIImageViewサブクラスである
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)") 
    } 
} 

:ハンドラは次のようになります。

この方法は、iOS 10の書籍(WWDCと同様)に記載されており、iOS 9でも同様に機能します。私はまだUIViewPropertyAnimatorベースのタップ検出を評価していますので、上記を行うにはUIViewPropertyAnimatorの使用方法の例を教えていただけたら、私はあなたの答えを正しいものとしてマークします。

1

達成しようとしていることはあまり明確ではありませんが、ジェスチャ認識機能をimageViewに追加して、parentViewに追加しないといけないと思います。

ので、この:

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

私はあなたを考えます funcにある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

動作しません。回答を参照してください転記しています。 – LNI

関連する問題