无法找到解决方案。
我正在构建一个具有大滚动视图的应用程序,它具有分页(水平)。 在这个滚动视图中,有一个UIView网格,每个网格中都有一个UIScrollview,有垂直滚动视图。
现在,重点是,当我分页我的'大'滚动视图时,有时触摸会卡在网格的UIViews中的一个小滚动视图中。
我不知道如何避免它 - 尝试使用hitTest但仍无法找到答案。
希望我很清楚......
感谢您的帮助。
编辑:
这是更大的滚动视图:
@implementation UIGridScrollView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
self.pagingEnabled;
return self;
}
@end
现在,在这个UIGridScroll View中,我添加了一个子视图:
@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中。
谢谢!
答案 0 :(得分:3)
@stanislaw,我刚试过你在iPhone设备上建议的解决方案。
我看到了你的问题。
您的代码确实可以防止偶尔滚动垂直视图,但我相信不是同步手势识别完成工作 - 注释您为内部视图提供的整个代码,并使用外部滚动视图的代码进行以下修改:< / p>
@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
答案 1 :(得分: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
将此子类用于水平视图或所有垂直滚动视图都应该足够了。
您尝试以这种方式使用后,实际上可能会发现您更喜欢默认行为。允许两个视图同时滚动几乎总是会导致意外的垂直滚动,同时向左和向右滑动,这可能会令人恼火(大多数人不会做一个完美的水平滑动手势)。
答案 2 :(得分:0)
我是这样做的:
在垂直滚动视图中使用 shouldRecognizeSimultaneouslyWithGestureRecognizer (感谢@omz!)和自定义滑动手势识别器(参见类似问题
Horizontal scrolling UIScrollView with vertical pan gesture),我有以下设置:
@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:它只允许滚动垂直滚动视图,只有当自定义滑动手势被识别时(只有顶部或底部方向),所有其他手势都传递给外部滚动视图,而外部滚动视图只允许任何手势如果没有拖动内部滚动视图。
注意:滑动手势也不适用于慢速或微小滑动,但确实如此(参见上面引用问题的评论)。
我觉得它可以更容易完成,也许我稍后会重构它。
无论如何,现在外部滚动工作完美 - 它水平滚动,没有任何偶然的内部滚动视图垂直平移。
稍后更新:正如我之前所预料的那样,我的解决方案确实包含了不必要的代码:请参阅@burik的答案,而部分基于我的解决方案,它会从中获取这些内容。
答案 3 :(得分:0)
我对您的设置感到有些困惑,但您可能需要查看-[UIScrollView setDelaysContentTouches:]
。在处理嵌套滚动视图时,您可以使用它来添加一些优先级。
答案 4 :(得分:0)
一旦我面对这种情况&amp;我有以下工作来完成这项工作。
从UIScrollView&amp;中查看您的两个视图的子类你会没事的。在你的情况下,我可以看到你的UINoteView不是UIScrollView的子类,它是ScrollView&amp;的子类。从这个类中删除innerScrollView。
答案 5 :(得分:0)
我认为使用velocity来确定滚动方向是一种更好的方法:
- (BOOL)gestureRecognizerShouldBegin:(UIPanGestureRecognizer *)gestureRecognizer {
CGPoint velocity = [gestureRecognizer velocityInView:gestureRecognizer.view];
return fabs(velocity.y) > 3 * fabs(velocity.x);
}