12

touchesBegan親へのオーバーレイでタッチイベントを処理しようとしていますが、タッチ入力がその下のUIView兄弟に渡されることも許可しています。UIViewタッチイベントを処理し、「これが存在しないかのように次のレスポンダーに送信する」と言う簡単な方法があると思っていましたが、私が見つけることができるのは、nextResponder返されているように見えるメソッドだけです私のオーバーレイビューの親。その親は実際にはそのオーバーレイビューの次の兄弟にそれを渡していないので、通常はTrueまたはFalseの戻り値を取得してそれを伝えるタッチコールバックで達成される単純なタスクのように見えることを行う方法がわからないままです処理をウィジェット階層の下に維持するかどうか。

明らかな何かが欠けていますか?

4

2 に答える 2

3

hitTest:withEvent:遅い答えですが、代わりにオーバーライドしたほうがよいと思いますtouchesBegan。それはtouchesBegan単純なことをするだけのかなり「高レベル」の方法であるように私には思えます。そのため、イベントがさらに伝播された場合、そのレベルで変更することはできません。それを行うのに適した場所はhitTest:withEvent:.

この点の詳細については、この SO の回答もご覧ください。

于 2011-12-24T21:38:33.733 に答える
1

Joey さんが探している望ましい動作を理解しています。API には、兄弟ビューを使用したこの自動メッセージング チェーンの動作をサポートするものは見つかりませんでした。

私が最初に以下に書いたのは、タッチについて親 UIView に通知することに関してでした。これはまだ適用されますが、さらに一歩進んで、親UIViewに、オーバーレイの兄弟である各サブビューでSergioが説明したヒットテスト手法を使用させ、親UIViewに「do」を手動で呼び出させる必要があると思いますヒット テストに合格したサブビューのそれぞれで、something" メソッドを実行します。これらの兄弟ビューのそれぞれは、他の兄弟への通知を中止するか、チェーンを続行するかについて、BOOL 値を返すことができます。

このパターンを頻繁に使用していることに気付いた場合は、UIView にカテゴリ メソッドを追加して、ヒット テストをカプセル化し、ビューにセレクターを実行するように依頼することを検討してください。

私の元の答え

少しの手作業で、これを自分で配線できます。私はこれをしなければなりませんでしたが、いくつかのカスタムクラスを作成することが理にかなっている頻繁に繰り返されるユースケース (ボタンのオーバーレイビュー) があったため、うまくいきました。状況が似ている場合は、これらの手法のいずれかで十分です。

オプション 1: オーバーレイが見栄えを良くする以外に何もする必要がない場合は、 でタッチ処理を完全にオプトアウトしuserInteractionEnabled = NOます。これにより、タッチ イベントがその親 UIView (オーバーレイされているもの) に移動するようになります。

オプション 2: オーバーレイにタッチ イベントを吸収させ (デフォルトのように)、親 UIView でメソッドを呼び出して、タッチまたは特定のジェスチャが認識されたことを示します。このようにして、他の誰かが傍受したとしても、オーバーレイの背後にある UIView は引き続きタッチ認識に作用します。

オプション 2 では、やUIControlEventなどの単純な型により適しています。私の場合 (その上にカスタム オーバーレイ ビューを持つカスタム サブクラス)、ボタンのタッチダウン イベントとタッチアップ イベントを 2 つの別々のメソッドに接続します。これらは、ボタン自体でタッチダウンまたはタッチアップ内部イベントが発生した場合に発生します。しかし、これらは、ボタンが押されたことをシミュレートする必要がある場合に、オーバーレイ ビューから呼び出すことができるフックでもあります。UIControlEventTouchDownUIControlEventTouchUpInsideUIButton

必要に応じて、オーバーレイとその親 UIView の間に既知のプロトコルを設定するか、オーバーレイに UIView を非公式にテストさせることができます。呼び出したいカスタム メソッドをrespondsToSelector:呼び出す前に、UIView が自動的に起動するようにチェックします。performSelector:オーバーレイで覆われていませんでした。

于 2012-01-01T15:20:08.860 に答える