0

各UIViewのdrawRect:メソッドを介して描画したやや複雑な形状のUIViewがいくつかあります。パスへの参照を(CGPathプロパティを介して)保存し、それをtouchesメソッドで使用して、タッチが実際にパスまたはシェイプ(CGPathContainsPoint)内にあるかどうかを検出しています。形状のために、透明なビューの領域があります(ビューのbackgroundColorプロパティがclearColorなどに設定されていると仮定すると、明らかに正方形/長方形でないものはすべて透明な領域になります)。

ビューが上に表示されたり、重なり合ったりする状況(頻繁に発生する)の場合、タッチが実際にCGPathまたはシェイプ内にあるかどうかを確認するために、タッチメソッド(touchesBeganなど)でテストしています。タッチが形状内にない場合は、タッチを下の次のビューに転送して、その要件を満たしているかどうかを確認します。

残念ながら(そして私の残念なことに)、これは実際にビューにバインドされているタッチと同じようには動作しません。私はこの問題を、特に1つを除いて、あらゆる方法で回避してきました。各ビューはUIRotationGestureRecognizerを使用しています。ただし、タッチが別のビューの透明な領域で発生し、そのビューがそのタッチをその下のビューに転送する場合、UIGestureRecognizerはトリガーされません。

私はこれをあらゆる角度から見てきました。タッチを適切なビューに実際に再割り当てまたはバインドする方法を考えようとしましたが、これが可能かどうかはわかりません。ビューがタッチを別のビューに転送している限り、タッチは最初にタッチを受け取った元のビューにバインドされたままになります。

UIApplicationまたはUIWindowをサブクラス化し、sendEvent: "メソッドをオーバーライドすることで、この方法で何かを実行できるかどうか疑問に思います。Appleがこれでどのような制御を提供するかは正確にはわかりません。プライベートにアクセスする可能性のあることは、何もする余裕がありません。 APIの。実際には、タッチがそれに属しているとビューが判断できるように、タッチを再割り当てする方法が必要です。

何か案は?'

4

1 に答える 1

2

これを行うには、UIViewをサブクラス化するか、UIGestureRecognizerをサブクラス化します。

UIViewのサブクラス化

UIView(またはそのサブクラスのいずれか)をサブクラス化し、オーバーライドする

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

ビュー内にあると見なされるポイントを決定できます。パスの外側のポイントについては、単に戻りますNO

UIGestureRecognizerのサブクラス化

UIGestureRecognizer(またはそのサブクラスのいずれか)をサブクラス化し、オーバーライドする

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

ジェスチャレコグナイザが認識すべきタッチを決定できます。パス外のすべてのタッチについては、呼び出す必要があります(サブクラスではありません)

- (void)ignoreTouch:(UITouch *)touch forEvent:(UIEvent *)event

あなた自身に。


パスの内側を指しますか?

どちらの場合でも、ポイントが保存したと言うパスの内側にあるかどうかを知る必要があります。

パスがすでにUIBezierPathsとして保存されている場合は、単に呼び出すことができます

- (BOOL)containsPoint:(CGPoint)point

ベジェパス上。ポイントまたはタッチを呼び出すことにより、パスと同じビュー座標に変換する必要がある場合があります

- (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view

また

- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view

あなたの見解では。

パスがCGPathとして保存されている場合は、を使用してパスからUIBezierPathを作成できます。

[UIBezierPath bezierPathWithCGPath:CGPath]; 
于 2012-05-11T19:06:57.607 に答える