また、UIPanGestureRecognizer の shouldBegin メソッドで値を読み取ろうとすると、ユーザーが少し移動した後 (つまり、ジェスチャーがパンを認識し始めたとき) にのみその位置が表示されることに気付きました。このパン ジェスチャが実際に開始された場所を知ることは非常に便利です。これにより、認識すべきかどうかを判断できます。
UIGestureRecognizer ビューをサブクラス化したくない場合は、次の 2 つのオプションがあります。
- UILongPressGestureRecognizer、遅延を 0 に設定
- UIPanGestureRecognizer、および shouldReceiveTouch での開始点のキャプチャ
他のジェスチャ (タップ、ダブルタップなど) がある場合は、オプション 2 が必要になる可能性があります。遅延が 0 のジェスチャ レコグナイザを長押しすると、他のジェスチャが正しく認識されなくなるためです。
他のジェスチャーを気にせず、パンのみを適切に機能させたい場合は、UILongPressGestureRecognizer を遅延 0 で使用できます。開始を手動で追跡する必要がないため、維持が容易になります。点。
解決策 1: UILongPressGestureRecognizer
良い点: シンプル
悪い点: 他のジェスチャー ハンドラーとうまくやっていく
ジェスチャを作成するときは、minimumPressDurationをに設定して0
ください。これにより、すべてのデリゲート メソッド (begin など) が最初のタッチを適切に受け取ることが保証されます。
UILongPressGestureRecognizer は継続的なジェスチャレコグナイザーであるため (個別のジェスチャ レコグナイザーではなく)、UIPanGestureRecognizer (継続的なジェスチャ レコグナイザーでもある) の場合と同様に、 UIGestureRecognizer.State.changedプロパティを処理することで動きを処理できます。基本的に、2 つのジェスチャを組み合わせています。
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(gestureHandler(_:))
gestureRecognizer.minimumPressDuration = 0
解決策 2: UIPanGestureRecognizer
用途: 他のジェスチャ レコグナイザーとうまく組み合わせる
悪い点: 開始状態を保存するのにもう少し手間がかかる
手順:
まず、デリゲートとして登録し、shouldReceiveTouch イベントをリッスンする必要があります。
それが発生したら、タッチポイントを何らかの変数に保存します (ジェスチャ ポイントではありません!)。
実際にジェスチャを開始するかどうかを決定するときが来たら、この変数を読み取ります。
var gestureStartPoint: CGPoint? = nil
// ...
let gestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(gestureHandler(_:))
gestureRecognizer.delegate = self
// ...
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
gestureStartPoint = touch.location(in: self)
return true
}
警告:前者が開始位置を正確に取得する唯一の方法であるため、必ず読んtouch.location(in: self)
でください。gestureRecognizer.location(in: self)
gestureStartPoint
次のように、好きな場所で使用できるようになりました。
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return isValidStartPoint(gestureStartPoint!)
}