26

ビュー コントローラー (UIViewController のカスタム サブクラス) でいくつかの UI コンポーネントのタッチを処理しています。touchesBegan:withEvent:touchesMoved:withEvent:、および のメソッドがありtouchesEnded:withEvent:ます。正常に動作していました。次に、スクロール ビュー (UIScrollView) を階層の最上位ビューとして追加しました。

現在、ビュー コントローラーのタッチ ハンドラーが機能しません。彼らは呼ばれません。興味深いのは、スクロール ビュー内に動作する他のさまざまな UI コンポーネントがあることです。一部はボタンで、一部は独自の を定義するカスタム ビューtouchesBegan:withEvent:などです。機能しないのは、ビュー コントローラーのタッチ ハンドラーだけです。

スクロールビューが独自の目的でこれらのタッチをインターセプトしているためだと思いましたが、 UIScrollView をサブクラス化し、それを機能させることができるかどうかを確認するために、YES常に からtouchesShouldBegin:withEvent:inContentView:NO常に から戻っていtouchesShouldCancelInContentView:ます。それでもうまくいきません。

それが違いを生む場合、私のビューコントローラーはタブバーコントローラー内にありますが、それは関係ないと思います。

誰かがこの問題を抱えていて、すぐに解決策を持っていますか? 私の推測では、スクロール ビューはレスポンダー チェーンを上っていきます。私はそれを元に戻すことができますか?他に何もわからない場合は、スクロール ビューの下のトップ レベル ビューをカスタム ビューにして、メッセージをビュー コントローラーに転送しますが、扱いにくいようです。

4

5 に答える 5

22

UIScrollView クラスのサブクラスを作成し、touchesBegan: およびその他のタッチ メソッドを次のようにオーバーライドします。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
  if (!self.dragging){ 
    [self.nextResponder touchesBegan: touches withEvent:event]; 
  }
  else{
    [super touchesBegan: touches withEvent: event];
  }
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{

// If not dragging, send event to next responder
    if (!self.dragging){ 
     [self.nextResponder touchesMoved: touches withEvent:event]; 
   }
   else{
     [super touchesMoved: touches withEvent: event];
   }
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

  // If not dragging, send event to next responder
   if (!self.dragging){ 
     [self.nextResponder touchesEnded: touches withEvent:event]; 
   }
   else{
     [super touchesEnded: touches withEvent: event];
   }
}
于 2012-01-30T09:16:37.303 に答える
2

これはうまくいきましたが、nextResponder は、サブクラスでオーバーライドすることが「推奨」されている UIView メソッドの 1 つではないため、「うまくいく」かどうかはわかりません。

@interface ResponderRedirectingView : UIView {

    IBOutlet UIResponder *newNextResponder;

}

@property (nonatomic, assign) IBOutlet UIResponder *newNextResponder;

@end


@implementation ResponderRedirectingView

@synthesize newNextResponder;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (UIResponder *)nextResponder {
    return self.newNextResponder;
}

- (void)dealloc
{
    [super dealloc];
}

@end

次に、Interface Builder で、スクロール ビューのダイレクト サブビューをこれらの 1 つに作成し、その newNextResponder をフックして、スクロール ビューをスキップし、ビュー コントローラーを直接ポイントするようにしました。

これも機能し、 nextResponder のオーバーライドを次のオーバーライドに置き換えます。

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.newNextResponder touchesBegan:touches withEvent:event];
}

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.newNextResponder touchesMoved:touches withEvent:event];
}

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.newNextResponder touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.newNextResponder touchesCancelled:touches withEvent:event];
}
于 2011-09-16T16:23:33.397 に答える
0

「問題なく動作していました。次に、階層の最上位ビューとしてスクロール ビュー (UIScrollView) を追加しました。」

あなたのスクロールビューは、アイテムを含むコンテンツビューの上にありますか?

すべてのコンポーネントは、スクロールビューの背後にあるビューではなく、スクロールビューにある必要があります

于 2011-09-16T01:39:41.413 に答える
-1

touchesBegan:etc メソッドはa で呼び出されることはありません。これは、これらのメソッドUIScrollViewのサブクラスでUIViewあり、これらのメソッドをオーバーライドするためです。ここでUIScrollView利用可能なさまざまな方法を確認してください。回避策は、何を実装するかによって異なります。

于 2011-09-16T16:39:16.260 に答える