1. ホーム
  2. iphone

UIViewsの下にあるタッチを通過させる

2023-10-25 06:17:24

質問

私は UIView があり、そこに 4 つのボタンがあり、さらに別の UIView があります。 一番上のビューには UIImageViewUITapGestureRecognizer をつける。

私が作成しようとしている動作は、ユーザがタップしたときに UIImageView をタップすると、画面の右下隅に小さく表示されたり、大きく表示されたりします。 大きいときはボトムビューのボタンを無効にし、小さくて右下にあるときはタッチをボタンに伝え、通常通り動作するようにしたいのです。 あと一息なのですが、ボタンにタッチを通すには UserInteractions を無効にしないとボタンにタッチが通りません。

私はこれを自分の initWithFrame: をトップビューで表示します。

// Add a gesture recognizer to the image view
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTapped:)];
tapGestureRecognizer.cancelsTouchesInView = NO;
[imageView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

そして、これは私の imageTapped: メソッドです。

- (void) imageTapped:(UITapGestureRecognizer *) gestureRecognizer {
    // Toggle between expanding and contracting the image
    if (expanded) {
        [self contractAnimated:YES];
        expanded = NO;
        gestureRecognizer.cancelsTouchesInView = NO;
        self.userInteractionEnabled = NO;
        self.exclusiveTouch = NO;
    }
    else {
        [self expandAnimated:YES];
        expanded = YES;
        gestureRecognizer.cancelsTouchesInView = NO;
        self.userInteractionEnabled = YES;
        self.exclusiveTouch = YES;
    }
}

上記のコードでは、画像が大きいときはボタンは無効で、画像をタッチすると縮小してボタンが有効になります。 しかし、小さい画像はタッチを受け取らないため、拡大されません。

もし私が self.userInteractionEnabled = YES を設定すると、画像はタッチすると拡大・縮小しますが、ボタンはタッチを受けず、無効のように動作します。

画像がタッチされたときに拡大および縮小し、画像が縮小状態にある場合にのみ、その下のボタンがタッチを受け取るようにする方法はありますか? 私はここで何か愚かなことをしており、明白な何かを見逃していませんか?

私はこれを動作させるために絶対に狂いそうなので、どんな助けも感謝されます。

デイブ

UPDATEです。

さらにテストするために、私は touchesBegan:touchesCancelled: メソッドを作成し、UIImageView を含むビューでそれらのスーパー実装を呼び出します。 上記のコードで touchesCancelled: は決して呼び出されず touchesBegan: は常に呼び出されます。

つまり、ビューがタッチを取得しているように見えますが、その下のビューに渡されていないだけなのです。

UPDATE

これはレスポンダチェーンの仕組みが原因でしょうか? 私のビューの階層はこのようになっています。

VC - View1
     -View2
      -imageView1 (has tapGestureRecogniser)
      -imageView2
     -View3
      -button1
      -button2

OSが最初にhitTestを行い、View2が前面にあるためすべてのタッチを取得するはずで、userInteractionsがView2に対してNOに設定されていない限り、これらはView3へ渡されることはなく、その場合imageView1もタッチを受信できないようになると考えています。 このように動作するのでしょうか?また、View2がView3にタッチを渡す方法はあるのでしょうか?

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

UIGestureRecognizerは赤信号だと思います。 最終的には pointInside:withEvent: メソッドをオーバーライドしました。 UIView:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    BOOL pointInside = NO;

    if (CGRectContainsPoint(imageView.frame, point) || expanded) pointInside = YES;

    return pointInside;
}

これは、imageViewのどちらかをタッチするか、その拡張フラグが設定されている場合、ビューがすべてのタッチをトラップするようにします。 拡張されていない場合は、タッチがimageView上にある場合のみトラップします。

NOを返すことによって、トップレベルのVCのViewは、ヒットを探してそのビュー階層の残りの部分にクエリを実行します。