6

找不到解决方案。

我正在构建一个具有大滚动视图的应用程序,它具有分页(水平)。在这个滚动视图内部,有一个 UIView 的网格,每个内部都有一个 UIScrollview,带有垂直滚动视图。

现在,重点是,当我分页我的“大”滚动视图时,有时触摸会卡在网格 UIView 内的一个小滚动视图中。

我不知道如何避免它 - 尝试使用 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

以下是我的做法:

在垂直滚动视图中使用shouldRecognizeSimultaneouslyWithGestureRecognizer(感谢@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;
}

这段代码有点 hacky:只有当他们的自定义 Swipe 手势被识别(仅顶部或底部方向)时,它才允许滚动垂直滚动视图,所有其他手势都传递给外部滚动视图,而外部滚动视图又允许任何手势,只有在没有人的情况下的内部滚动视图正在被拖动。

注意:滑动手势也适用于缓慢或微小的滑动并不明显,但确实如此(另请参阅上面引用的问题的评论)。

我觉得它可以更容易完成,也许我稍后会重构它。

不管怎样,现在外滚动条完美地工作了——它水平滚动,没有任何偶尔的垂直平底滚动视图。

后期更新:正如我之前预期的那样,我的解决方案确实包含不必要的代码位:请参阅@burik 的答案,虽然部分基于我的解决方案,但它会将这些位排除在外。

于 2013-04-17T23:10:04.213 回答
0

一旦我遇到这种情况,我就有以下工作要做。

从 UIScrollView 子类化你的两个视图&你会很好的。在您的情况下,我可以看到您的 UINoteView 不是 UIScrollView 的子类,将其从 ScrollView 子类化并从此类中删除 innerScrollView。

于 2013-04-23T12:22:54.803 回答
0

我认为使用速度来确定滚动方向是一种更好的方法:

- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer {
    CGPoint velocity = [gestureRecognizer velocityInView:gestureRecognizer.view];
    return fabs(velocity.y) > 3 * fabs(velocity.x);
}
于 2013-10-25T13:58:45.677 回答
0

我对你的设置有点困惑,但你可能想看看-[UIScrollView setDelaysContentTouches:]. 在处理嵌套滚动视图时,您可以使用它来添加一些优先级。

于 2013-04-23T02:50:02.970 回答
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 回答