1. ホーム
  2. ios

[解決済み] iOSのイベントハンドリング - hitTest:withEvent:とpointInside:withEvent:はどのように関係しているのでしょうか?

2022-05-10 23:48:35

質問

多くのアップルの文書は非常によく書かれていますが、私は、' iOS のためのイベント処理ガイド は例外だと思います。そこに記述されていることを明確に理解するのは難しいです。

ドキュメントによると

ヒット・テストにおいて、ウィンドウが呼び出す hitTest:withEvent: を呼び出します。このメソッドは、ビュー階層の最上位にあるビューに対して再帰的に pointInside:withEvent: を再帰的に呼び出し、タッチが行われた境界内のサブビューを見つけるまで、階層を下っていきます。そのビューがヒットテストビューになります。

ということは hitTest:withEvent: のみが呼び出され、システムからは pointInside:withEvent: を呼び出し、特定のサブビューからのリターンがYESの場合、そのサブビューの pointInside:withEvent: を呼び出し、そのサブビューのサブクラスの?

どのように解決するのですか?

それは非常に基本的な質問のようです。しかし、私はあなたと同意する文書が他の文書ほど明確ではないので、ここに私の答えがあります。

の実装は hitTest:withEvent: をUIResponderで実装すると、次のようになります。

  • を呼び出します。 pointInside:withEvent:self
  • リターンがNOの場合 hitTest:withEvent: が返されます。 nil .終わりです。
  • リターンがYESの場合、以下を送信します。 hitTest:withEvent: メッセージをそのサブビューに送ります。 はトップレベルのサブビューから始まり、他のビューへと続きます。 が非 nil オブジェクトを返すか、すべてのサブビューがメッセージを受信するまで、他のビューに続きます。
  • サブビューが非 nil オブジェクトを返した場合、最初の hitTest:withEvent: はそのオブジェクトを返します。 で終わりです。
  • を返すサブビューがない場合、非 nil オブジェクトを返さない場合、最初の hitTest:withEvent: が返す self

この処理は再帰的に繰り返されるため、通常は最終的にビュー階層のリーフビューが返されます。

しかし hitTest:withEvent を上書きして別のことをすることもできます。多くの場合、オーバーライドされた pointInside:withEvent: をオーバーライドする方がシンプルで、アプリケーションのイベント処理を調整するのに十分なオプションを提供します。