10

注:UIScrollViewサブビューへのタッチの送信に関するいくつかの質問をすでに読みました(これには含まれており、賛成票を投じましたが、意図したとおりに機能しなくなりました)。

私が持っているもの:全体をカバーUIScrollViewするカスタム( AUIViewと呼びましょう)を内部に持っています。A の中に他のカスタムを入れることもできます。UIScrollViewUIViews

コードで私はこれをやっています:

[scrollView setDelaysContentTouches:YES];
scrollView.canCancelContentTouches = NO;

何が起こっているか:現時点で私の唯一の問題は、A内でサブビューを移動したい場合は、それに触れて待ってから移動する必要があることです。まさにここに記載されているとおり:

これで、UIView の最初のタッチの「時間の長さ」に応じて動作が変わります。短い場合、相対的なドラッグは UIScrollView のスクロールとして管理されます。長い場合は、UIView 内で touchesMoved: イベントを取得しています。

私が欲しいもの: A内のサブビューは常に優先されるべきであり、触れて待つ必要はありません。サブビューではなくAに触れた場合UIScrollView、パンや移動などのタッチを に受け取りたい(contentSizeは よりも大きいframe)。


編集 1.0

このAビューをジェネリック内に持つ唯一の理由は、 AUIScrollViewビューをズームイン/ズームアウトできるようにしたいからです。だから私は次のことをやっています:

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return customView; // this is the A view
}

最初は、内部にAビューがありませんでした。ルート ビューのサブビューとしてAUIScrollViewを追加するだけで、すべてがうまくいきました。ズームイン/ズームアウトを有効にする別の方法があれば、喜んで答えます。UIViewController's

4

4 に答える 4

8

注:特に Aaron Hayman への貢献に感謝します。

UIScrollView私が持っていたサブクラスで次のことを行うことで、それを理解することができました:

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
   CGPoint pointOfContact = [gestureRecognizer locationInView:self];

    // The view with a tag of 200 is my A view.
    return (![[self hitTest:pointOfContact withEvent:nil] isEqual:[self viewWithTag:200]]);
}
于 2012-08-15T11:54:02.517 に答える
4

私はこれをテストしていませんが、ビュー A (またはそのサブビュー) でタッチ イベントをどのように処理しているかによって、タッチ イベントがどのように渡されるかが決まると思います。具体的には、 a の代わりに 、 、 などtouchesBegantouchesMovesメソッドを使用しようとすると、希望する方法でタッチを受け取ることができません。Apple は、あなたが直面しているような問題を処理するように を設計しています。具体的には、スクロールを処理するために使用します。これらのサブビューの 1 つで発生する「パン」の各サブビューにを追加すると、 . ただし、単に「生の」メソッドを使用している場合、inはキャンセルされません。 touchesEndedUIGestureRecognizerUIGestureRecognizerUIScrollViewUIPanGestureRecognizerUIPanGestureRecognizerView AUIScrollViewtouchesUIPanGestureRecognizerUIScrollView

UIGestureRecognizer一般に、タッチをビューで直接処理するのではなく、a を使用するのがほとんどの場合に最適です。標準が提供できない方法でタッチを処理する必要がある場合は、そこでタッチUIGestureRecognizerをサブクラス化UIGestureRecognizerして処理します。UIGestureRecognizerそうすれば、独自のカスタム タッチ処理と共にのすべての機能を取得できます。UIGestureRecognizerAppleは、開発者が使用するカスタム タッチ処理コードのほとんど (すべてではないにしても) を置き換えることを意図していたと思いますUIView。これにより、コードの再利用が可能になり、どのコードがどのタッチ イベントを処理するかを軽減する際の対処がはるかに簡単になります。

于 2012-08-14T12:01:43.853 に答える
0

イベントを渡すには、「touchesBegan、touchesMoved、touchesEnded」を使用したほうがよいと思います。

あなたはこのようにすることができます:

mainView を作成する必要があります。2 つのプロパティがあります。1 つは yourScrollView A で、もう 1 つは yourCustomView です。

`[yourScrollView addSubviews:yourCustomView];
[mainView addSubviews:yourScrollView];`

次に、このように mainView.m に touches メソッドを記述します (scrollView ステートメントは無視してください)。

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

    UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
   if ([[touches allObjects] isKindOfClass:[yourCustomView class]]) 
   {

        //do whatever you want
   }

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

    UITouch *mytouch=[[touches allObjects] objectAtIndex:0];
   if ([[touches allObjects] isKindOfClass:[yourCustomView class]]) 
   {
       //do whatever you want
   }
}

最後のステップ: イベントを scrollView (your A) のサブビューに渡します。

#import "yourScrollView.h"


@implementation yourScrollView


- (id)initWithFrame:(CGRect)frame {

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

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesBegan:touches withEvent:event];
    if(!self.dragging)
        [[self nextResponder] touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesMoved:touches withEvent:event];
    if(!self.dragging)
        [[self nextResponder] touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesEnded:touches withEvent:event];
    if(!self.dragging)
        [[self nextResponder] touchesEnded:touches withEvent:event];
}

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


@end 

あなたを助けたい

于 2012-08-14T10:20:59.760 に答える
0

ジャッキー、私も同様のことが必要でした: 建築計画 (あなたの A、私の場合は UIScrollView のサブクラス) 内で、ユーザーがオブジェクトを配置およびサイズ変更できるようにします (それらを B と呼びます)。これは、この動作に到達するのにかかったもののスケッチです。

  • スーパービューの (A)initWithFrame:メソッドで、次の 2 つを設定します。

    self.canCancelContentTouches = YES;
    self.delaysContentTouches = NO;
    

    これにより、B のタップがすぐに B にルーティングされます。

  • 埋め込まれた B で、スーパービュー A がタップをキャンセルしないようにして、B で開始されたジェスチャを妨げないようにします。

    このメソッドでは、 が見つかるまで (ビューのプロパティをtouchesBegan:使用して) ビュー階層を上方向に検索し、それを に設定します。変更したスーパービューを記憶し、 Bのおよびメソッドでこのプロパティを復元します。superviewUIScrollViewcanCancelContentTouchesNOtouchesEndedtouchesCancelled

これがあなたにも当てはまるかどうか興味があります。幸運を!

のび

于 2012-08-14T09:25:08.313 に答える