0

画面に表示されるサブビュー画像のグリッドがあります。これは基本的に、一連の画像をチェッカー ボードのように画面に並べたものです。これらの画像サブビューのそれぞれにジェスチャ認識機能を追加して、ユーザーが画像サブビューのいずれかに触れたときにサブビュー、つまり座標、タグなどを取得できるようにしたいだけです。ビュー階層は次のようになります。

  1. スーパービュー
  2. gridContainer ビュー
  3. および個々のサブビュー - 画像付き

アップルのドキュメントを見ると、ジェスチャー認識機能を gridContainer ビューに追加できるようになり、各サブビュー (画像付き) がジェスチャー認識機能を継承する必要があるようです。これまでのところ、これが私が試したことです。ゲッターでグリッドコンテナービューを初期化しました。また、getter で createGesture メソッドを呼び出しました。これは、ジェスチャ認識機能を gridContainer ビューに追加することになっています。ただし、実行時にアクションの handleSingleTap メソッドを指しているエラーが発生します。EXC_BAD_EXCESS を読み取ります。また、gridContainer ビューの外側のビューがタッチ イベントに応答しないようにすることも注目に値します。助けてくれてありがとう。

実装しようとしているコードは次のとおりです。

- (UIView *)gridContainerView
{
    if (!_gridContainerView)_gridContainerView = [[UIView alloc] init];
    [self createGesture];
    return _gridContainerView;
}
- (void)createGesture
{
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]
                                         initWithTarget:self.gridContainerView
                                         action:@selector(handleSingleTap:)];
    singleTap.numberOfTapsRequired = 1;

    [self.gridContainerView addGestureRecognizer:singleTap];
}

これを理解するために追加のコードが必要な場合は、お知らせください。

編集: handleSingleTap メソッドを含む:

- (IBAction)handleSingleTap:(id)sender
{
    CGPoint tapPoint = [sender locationInView:sender];
    NSLog(@"sender = %@",sender);
    NSLog(@"tappoint = %@", tapPoint);
}
4

3 に答える 3

4

UIViewgridContainerViewのプレーンを初期化しています。次に、ジェスチャレコグナイザーをアタッチします(そのビューインスタンスをターゲットとして使用します)。ただし、プレーンUIViewは実装されていないhandleSingleTap:ため、例外が発生します。

UIViewトリガーするジェスチャに必要なセレクターを実装する(カスタム派生)クラスを作成する必要があります。

于 2012-04-21T13:08:40.447 に答える
0

すぐにいくつかの問題が発生します (ジェスチャーの処理に対処することさえしません)。

gridContainerView にアクセスするたびに createGesture を呼び出します。おそらく、ビューを作成するときにのみこれを実行したいでしょう。さらに、createGesture を見ると、gridContainerView にコールバックし、createGesture にコールバックし、gridContainerView にコールバックします。

あなたはおそらくもっと似たものが欲しい...

- (UIView *)gridContainerView
{
    if (!_gridContainerView) {
        _gridContainerView = [[UIView alloc] init];
        [self createGesture];
    }
    return _gridContainerView;
}

次に、ビューで handleSingleTap を呼び出そうとしています。おそらくコントローラー上でそれが必要になるでしょう: initWithTarget:self.

- (void)createGesture
{
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]
                                         initWithTarget:self
                                         action:@selector(handleSingleTap:)];
    singleTap.numberOfTapsRequired = 1;

    [self.gridContainerView addGestureRecognizer:singleTap];
}

おそらく、このように互いに直接参照する 2 つの別々のメソッドを持つという知恵を結び直したいと思うでしょう。ただし、少なくともアクセサーに加えた変更は問題ありません。アクセサーにさらにコードを追加する場合は、createGesture を呼び出す前にビューを完全にセットアップする必要があることに注意してください。

于 2012-04-21T13:25:56.857 に答える
0

いくつかのこと。まず、gridContainerView を標準の UIView としてインスタンス化し、それからメッセージ handleSingleTap: を送信しますが、これには応答しません。gridContainerView をメッセージに応答させたい場合は、UIView をサブクラス化し、適切なメソッドを作成し、gridContainerView をサブクラスとしてインスタンス化する必要があります。

次に、全体的なアプローチとして、gridContainerView のサブクラスを作成し (そう呼ぶこともある)、ジェスチャを処理するメソッドを作成します。そのメソッドでは、UIGestureRecognizer メソッドを使用して、タッチ/タップされたポイントにアクセスできますlocationInView:。この時点を使用して、gridContainerView 内のどのサブビューがタップされたかを判断し、適切なアクションを実行します。どのサブビューがタップされたかを検出するには、サブビューを繰り返し処理し、各サブビューをチェックして、タップされたポイントが含まれているサブビューを特定します。これを行うために使用できる UIView のメソッドがいくつかあります。

pointInside:withEvent: hitTest:withEvent:

イベントにはパスできますnil。上記の 2 つのことは、少し異なることを行います。ポイントがビュー内にあるかどうかをテストするだけの場合は、 as を使用pointInside:withEventして を返しますBOOL。このメソッドhitTest:withEventにより、ビューはすべてのサブビューを検索し、それ自体またはそのサブビューの 1 つを返します (ポイントが境界外にある場合は nil を返します)。 hitTest:withEventプロセッサの負荷が少し高くなる可能性があります。また、CGRectContainsPoint()テストにも使用できます。

于 2012-04-21T13:26:04.657 に答える