6

その解決策を見つけることができませんでした。

ページング(水平)を備えた大きなスクロールビューを備えたアプリを構築しています。このスクロール ビュー内には、UIView のグリッドと、それぞれの内部に垂直スクロール ビューを持つ UIScrollview があります。

ポイントは、「大きな」スクロールビューをページングしているときに、グリッドのUIView内の小さなスクロールビューの1つでタッチが動かなくなることがあります。

回避方法がわかりません - hitTest でトリックを試みましたが、まだ答えが見つかりませんでした。

私がはっきりしていることを願っています...

ご協力いただきありがとうございます。

編集:

これはより大きなスクロールビューです:

@implementation UIGridScrollView
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    self.pagingEnabled;
    return self;
}
@end

さて、この UIGridScroll ビューに、このビューをサブビューとして追加しました:

@implementation UINoteView
{
IBOutlet UIScrollView *_innerScrollView; // this scrollview frame is in the size of the all UINoteView
}

- (void)awakeFromNib
{
    _innerScrollView.contentSize = CGSizeMake(_innerScrollView.frame.size.width, _innerScrollView.frame.size.height+50.0f);
}
@end

ページングは​​うまく機能し、内側のスクロール ビューもうまく機能しますが、より大きなメモ ビューをページングすると、_innerScrollView で指が動かなくなることが何度もありました。

ありがとう!

4

6 に答える 6

3

@stanislaw、iPhone デバイスで提案されたソリューションを試してみました。

私はあなたの問題を見ます。

あなたのコードは垂直ビューの時折のスクロールを防ぎますが、同時ジェスチャー認識が仕事をしているとは思いません.内側のビューに提供するコード全体をコメントし、次の変更を加えて外側のスクロールビューのコードを使用します:

@interface OuterHorizontalScrollView : UIScrollView ...
@property (weak) InnerVerticalScrollView *currentActiveView; // Current inner vertical scroll view displayed.
@end

@implementation OuterHorizontalScrollView
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (self.currentActiveView.dragging == NO) {
        self.currentActiveView.scrollEnabled = NO; // The presence of this line does the job
    }
    return YES;
}

- (void)scrollViewDidEndDragging:(PlacesScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    self.currentActiveView.scrollEnabled = YES; // This is very likely should be done for all subviews, not only a current.
}    
@end
于 2013-04-24T05:47:24.153 に答える
0

この状況に直面したら、これを行うために次の回避策があります。

UIScrollView から両方のビューをサブクラス化してください。これで問題ありません。あなたの場合、UINoteViewはUIScrollViewのサブクラスではなく、ScrollViewからサブクラス化し、このクラスからinnerScrollViewを削除することがわかります。

于 2013-04-23T12:22:54.803 に答える
0

これが私がやった方法です:

shouldRecognizeSimultaneouslyWithGestureRecognizer (thanks @omz!) とカスタム スワイプ ジェスチャレコグナイザーを垂直スクロール ビューで使用する (同様の質問を参照)

垂直パンジェスチャを使用した水平スクロール UIScrollView )、次の設定があります。

@interface UIScrollView (GestureRecognition) <UIGestureRecognizerDelegate>
@end

@interface OuterHorizontalScrollView : UIScrollView ...
@property (weak) InnerVerticalScrollView *currentView; // Current inner vertical scroll view displayed.
@end

@implementation OuterHorizontalScrollView
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (self.currentActiveView.placeVerticalScrollView.dragging == NO) {
        self.currentActiveView.placeVerticalScrollView.scrollEnabled = NO;
        return YES;
    } else {
        return NO;
    }
}    
@end

@interface InnerVerticalScrollView : UIScrollView...
@property UISwipeGestureRecognizer *swipeGestureRecognizer;
@end

@implementation InnerVerticalScrollView
- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        ...
        self.swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)];
        self.swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp;
        [self addGestureRecognizer:self.swipeGestureRecognizer];
    }

    return self;
}

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer == self.panGestureRecognizer && self.scrollEnabled == YES) {
        return YES;
    } else if (gestureRecognizer == self.swipeGestureRecognizer) {
        return YES;
    } else {
        self.scrollEnabled = NO;
    }

    return NO;
}

- (void)handleSwipeGesture:(UIGestureRecognizer *)sender {
    self.scrollEnabled = YES;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {    
    return YES;
}

このコードは少しハックです: カスタム スワイプ ジェスチャが認識された場合 (上方向または下方向のみ) にのみ垂直スクロール ビューのスクロールを許可し、他のすべてのジェスチャは外側のスクロール ビューに渡されます。の内側スクロール ビューがドラッグされています。

注: スワイプ ジェスチャが低速または小さなスワイプでも機能することは明らかではありませんでしたが、機能します (上記の引用された質問へのコメントも参照してください)。

もっと簡単に達成できると思うので、後でリファクタリングするかもしれません。

とにかく、外側のスクロールが完全に機能するようになりました-内側のスクロールビューの垂直方向のパンが時折発生することなく、水平方向にスクロールします。

後の更新:前に予想したように、私のソリューションには不要なコードが含まれていました: @burik の回答を参照してください。

于 2013-04-17T23:10:04.213 に答える
0

をサブクラス化UIScrollViewして実装gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:すると、スクロール ビューのビルトインpanGestureRecognizerが別のスクロール ビューのジェスチャ レコグナイザーと同時に認識できるようになります。

例:

//This is needed because the public UIScrollView headers
//don't declare the UIGestureRecognizerDelegate protocol:
@interface UIScrollView (GestureRecognition) <UIGestureRecognizerDelegate>
@end

@interface MyScrollView : UIScrollView

@end

@implementation MyScrollView

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if (gestureRecognizer == self.panGestureRecognizer) {
        return YES;
    } else if ([UIScrollView instancesRespondToSelector:@selector(gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:)]) {
        //Note: UIScrollView currently doesn't implement this method, but this may change...
        return [super gestureRecognizer:gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:otherGestureRecognizer];
    }
    return NO; //the default
}

@end

このサブクラスを水平スクロール ビューまたはすべての垂直スクロール ビューに使用するだけで十分です。

このように使用してみると、実際にはデフォルトの動作の方が気に入っているかもしれません。両方のビューを同時にスクロールできるようにすると、ほとんどの場合、左右にスワイプしているときに誤って垂直方向にスクロールしてしまい、イライラすることがあります (ほとんどの人は完全に水平方向のスワイプ ジェスチャを行いません)。

于 2013-04-17T17:32:51.260 に答える