73

そのUIView上に4つのボタンがUIViewあり、ボタンビューの上に別のボタンがあります。一番上のビューには、UIImageViewが付いたが含まUITapGestureRecognizerれています。

私が作成しようとしている動作は、ユーザーがタップする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すると、タッチすると画像が拡大および縮小しますが、ボタンはタッチを受信せず、無効になっているように動作します。

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

私はこれを機能させようとして絶対に怒っているので、助けていただければ幸いです。

デイブ

アップデート:

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

そのため、ビューがタッチされているように見えますが、それらは下のビューに渡されていません。

アップデート

これは、レスポンダー チェーンの仕組みによるものですか? 私のビュー階層は次のようになります。

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

View2 が前面にあると言うように、OS は最初に hitTest を実行するので、すべてのタッチを取得する必要があり、View2 の userInteractions が NO に設定されていない限り、これらは View3 に渡されません。これはどのように機能し、View2 がそのタッチを View3 に渡す方法はありますか?

4

5 に答える 5

95

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 にタッチするか、その Expanded フラグが設定されている場合、ビューはすべてのタッチをトラップします。展開されていない場合は、imageView にある場合にのみタッチをトラップします。

NO を返すことにより、最上位の VC のビューは、ビュー階層の残りの部分を照会してヒットを探します。

于 2012-01-27T09:59:47.360 に答える
69

ViewあなたのインStoryboardまたはアンドを選択してくださいXIB...


ここに画像の説明を入力


またはスウィフトで

view.isUserInteractionEnabled = false
于 2015-06-22T18:27:15.293 に答える
6

UIGestureRecognizerDelegateプロトコルを調べます。具体的には、gestureRecognizer:shouldReceiveTouch:

UIGestureRecognizerあなたはそれぞれをあなたの財産にしたいでしょうUIViewController

// .h
@property (nonatomic, strong) UITapGestureRecognizer *lowerTap;

// .m
@synthesize lowerTap;

// When you are adding the gesture recognizer to the image view
self.lowerTap = tapGestureRecognizer

UIViewController必ず代理人にしてください。

[self.lowerTap setDelegate: self];

次に、あなたはこのようなものを持っているでしょう、

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if (expanded && gestureRecognizer == self.lowerTap) {    
        return NO;
    }
    else {
        return YES;
    }
}

もちろん、これは正確なコードではありません。しかし、これはあなたが従いたい一般的なパターンです。

于 2012-01-26T22:17:00.297 に答える
3

別の解決策があります。私は 2 つのビューを持っています。オーバーラップしていたビューと呼びましょうCustomSubView。両方ともタッチを受け取るはずです。ビュー コントローラーとカスタム UIView クラスがあり、ViewControllerViewインターフェイス ビルダーで設定したものを呼び出して、そのビューにタッチを受け取る 2 つのビューを追加しました。

ViewControllerViewそこで、 hitTest を上書きしてタッチをインターセプトしました。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    return self;
}

次に、次のように上書きしましたViewControllerView

- (void)touchesBegan:(NSSet *)touches
           withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    for (UIView *subview in [self.subviews reverseObjectEnumerator])
    {
        if ([subview isKindOfClass:[CustomSubView class]])
        {
            [subview touchesBegan:touches withEvent:event];
        }
    }
}

と でまったく同じことをtouchesMoved touchesEnded行いtouchesCancelledます。

于 2016-03-16T09:22:12.560 に答える