ウィンドウ内の CGPoint に基づいて、ヒットしたアクセシビリティ要素 (存在する場合) を判断しようとしています。これは可能ですか?アクセシビリティ要素のヒット テストの並べ替え... アクセシビリティ要素のヒット (作成されたシステムを含む) を返す必要があります。これを行う方法が必要なようです。
4 に答える
それを行うための2つの可能な方法。最初UIView
に、 (新しいファイル、カテゴリ、「タップ」という名前、「UIView」のサブクラス)のカテゴリを作成し、次のコードをその中に配置します。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
NSLog(@"%@", self);
}
これまでのところ、このコードはすべてUIView
のsで機能しますが、それ自体のすべてのサブクラスでは機能しません。UIControl
したがって、さらにいくつかのサブクラス(たとえば、、UIWindow
など)を作成する必要があります。これらのサブクラスでは、何もする必要はありません。次NSLog()
のように呼び出します。
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
}
これらのサブクラスはすべてスーパークラスを呼び出すため、最終的にはのを呼び出すことNSLog()
になりUIView
ます。欠点は、すべての場合に膨大な量のサブクラスを作成する必要があることです。たとえば、、、forUIView
などが必要です。UIControl
UIControl
UIButton
。
他の方法は、あなたが求めていたものとは異なりますが、はるかに簡単です。サブビューを再帰的に呼び出すだけです。
- (void)logView:(UIView*)v index:(int)i
{
NSMutableString *str = [NSMutableString string];
for (int u = 0; u<i; u++) { [str appendString:@"| "]; }
[str appendFormat:@"<%@ %p frame:%@>", v.class, v, NSStringFromCGRect(v.frame)];
// of course you can change it to display your accessibility hint/label
printf("%s\n", [str UTF8String]);
for (UIView *vv in v.subviews) { [self logView:vv index:i+1]; }
}
このメソッドを1回呼び出します。
[self logView:self.view index:0];
…そして、出力としてツリーを自動的に作成します。
<UITextField 0x6b30010 frame:{{20, 13}, {280, 31}}>
| <UITextFieldRoundedRectBackgroundView 0x6b31e00 frame:{{0, 0}, {280, 31}}>
| | <UIImageView 0x6b31fe0 frame:{{0, 0}, {0, 0}}>
| | <UIImageView 0x6b32070 frame:{{0, 0}, {0, 0}}>
| | <UIImageView 0x6b320e0 frame:{{0, 0}, {0, 0}}>
現在、最新の API でこれを行う方法はないようです。
私はあなたが望むものを達成するために、例えばブラウザがDOMでのイベント処理でキャプチャフェーズを行う方法を基本的に再実装する必要があるのではないかと心配しています:
- 最も一般的な要素から始めます — UIKit ベースのアプリでは、これはアプリケーションの
keyWindow
、または (アプリがマルチスクリーンの場合) 画面の最前面のウィンドウになりますwindowLevel
。 - 問題のオブジェクトがアクセシビリティ コンテナであるかどうかを確認し、
- もしそうなら、それに再帰して、適切なものを求めてください。
- そうでない場合は、それがアクセシビリティ要素であるかどうかを確認し、
- 保釈でないと。
- そうである場合は、そのアクセシビリティ フレームに問題のポイントが含まれているかどうかを確認します。
- その場合は、おめでとうございます。問題の要素を見つけることに成功したので、それを返す必要があります。
- そうでない場合は、保釈します。
ここまでで、アクセシビリティ要素とコンテナ内の要素のケースを処理しました。
カバーする追加のケースが 1 つあります。それは、それ自体がアクセシビリティ要素であるアクセシビリティ
コンテナーです。問題のポイントの要素を生成しなかったコンテナーがあります。
それがアクセシビリティ要素である場合、そのフレームにポイントが含まれているかどうかを確認し、含まれている場合は を返しself
、含まれていない場合は保釈します。
そして保釈とは、常にゼロを返すことを意味します。
すべてのロジックを取得し、コードに変換して、上のカテゴリに入れますNSObject
。
私の最良の答えは、すべてのアクセシビリティ要素を配列に追加することです。touchesEnded メソッドで、配列を列挙し、いずれかの要素がタッチされているかどうかを確認します。これを行う 1 つの方法は、要素の boundingBox に CGPoint が含まれているかどうかを確認することです。次に、そのタッチに応答するコードをたくさん書くことができます! これが役に立ったことを願っています!^_^