以下是滚动视图的工作方式:一个滚动视图是在水平方向启用分页。此滚动视图的每个“页面”都包含一个垂直滚动的UITableView。没有修改,这可行,但不完美。
不正确的行为:当用户在桌面视图中向上和向下滚动,但是想要快速浏览到下一页时,水平轻弹/滑动最初不起作用 - 在桌面视图静止之前它将无法工作(即使滑动非常明显是水平的)。
它应该如何工作:如果滑动显然是水平的,即使表格视图仍在滚动/弹跳,我也希望页面更改,因为这也是用户期望的。
如何更改此行为 - 最简单或最好的方法是什么?
注意由于各种原因,某些答案中所述的UIPageViewController不起作用。如何使用交叉方向UIScrollViews(/ one是一个表视图,但你明白了)?我几个小时以来一直撞在墙上 - 如果你认为你可以做到这一点,那么我会非常高兴地奖励赏金。
答案 0 :(得分:18)
根据我对这个问题的理解,只有在tableView滚动时我们才想改变默认行为。所有其他行为都是一样的。
子类UITableView
。 UITableView
是UIScrollView
的子类。在UITableView
子类上实现一个UIScrollView
的{{1}}委托方法
UIGestureRecognizer
因为我们只想在tableView减速时更改默认手势行为。
现在将所有'UITableView的类更改为新创建的tableViewSubClass并运行项目,在tableView滚动时滑动应该可以正常工作。 :
但是当tableView滚动时,滑动看起来有点过于敏感。让我们的滑动有点限制。
子类- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer
{
//Edit 1
//return self.isDecelerating;
//return self.isDecelerating | self.bounces; //If we want to simultaneous gesture on bounce and scrolling
//Edit 2
return self.isDecelerating || self.contentOffset.y < 0 || self.contentOffset.y > MAX(0, self.contentSize.height - self.bounds.size.height); // @Jordan edited - we don't need to always enable simultaneous gesture for bounce enabled tableViews
}
。在UIScrollView
子类上实现另一个UIScrollView
的委托方法UIGestureRecognizer
gestureRecognizerShouldBegin:
我们希望“滑动显然是水平的”。如果x轴上的手势速度是y轴上的手势速度,则上面的代码仅允许手势开始。 [如果您喜欢,请随意增加硬编码值“2”。滑动需要更高的水平值。]
现在将`UiScrollView'类(具有多个TableView)更改为ScrollViewSubClass。运行该项目。 :
我在gitHub上创建了一个项目https://github.com/rishi420/SwipeWhileScroll
答案 1 :(得分:3)
虽然苹果不太喜欢这种方法:
重要说明:您不应在UIScrollView对象中嵌入UIWebView或UITableView对象。如果这样做,可能会导致意外行为 因为两个对象的触摸事件可能混淆错误 处理。强>
我找到了实现这个目标的好方法。
这是该问题的完整解决方案。要在UIScrollView
滚动时滚动UITableView
,您需要停用相关的互动。
- (void)viewDidLoad
{
[super viewDidLoad];
_myScrollView.contentSize = CGSizeMake(2000, 0);
data = [[NSMutableArray alloc]init];
for(int i=0;i<30;i++)
{
[data addObject:[NSString stringWithFormat:@"%d",i]];
}
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self.view addGestureRecognizer:tap];
}
- (void)handleTap:(UITapGestureRecognizer *)recognizer
{
[_myTableView setContentOffset:_myTableView.contentOffset animated:NO];
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView
{
scrollView.userInteractionEnabled = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
scrollView.userInteractionEnabled = YES;
}
总结上述代码,如果UITableView
正在滚动,请将userInteractionEnabled
设置为NO
,以便UIScrollView
检测到滑动。如果UITableView
正在滚动并且用户点击屏幕,则userInteractionEnabled
将设置为YES。
答案 2 :(得分:0)
不要将UIScrollView
用作这些多个表视图的容器,而是尝试使用UIPageViewController
。
您甚至可以将其作为child view controller
(直接替换UIScrollView
)集成到现有的视图控制器设置中。
此外,您可能希望从UIPageViewControllerDataSource
以及可能UIPageViewControllerDelegate
中的一个或多个方法实施所需的方法。
答案 3 :(得分:0)
您是否尝试过表格和滚动的方法:directionalLockEnabled
并将它们设置为水平为一个而垂直为另一个?
修改:
<强> 1)强> 您想要做的事情非常复杂,因为触摸会等待一段时间(如0.1秒)来了解您的动作。如果你的桌子正在移动,它将立即触摸你的任何东西(因为它假设它是反应性运动)。
我没有看到任何其他解决方案,但是从头开始覆盖触摸移动以立即检测到你想要的那种方式(例如,如果移动将是水平的),但要做到这一点将会非常困难。
<强> 2)强> 我可以建议你的另一个解决方案是让你的桌子有左右边距,你可以触摸父卷轴(这样的页面的东西)然后即使你的桌子滚动,如果你触摸这里,只会触摸你的分页滚动。它更简单,但可能不适合您的设计......
答案 4 :(得分:0)
使用UIPageViewController
并使用-viewDidLoad
方法(或任何其他最符合您需求或设计的方法)获取UIPageViewController
的{{1}}子视图并指定一个代表它。请记住,它的委托属性不会是零。因此,您可以选择将其分配给另一个引用,然后将符合UIScrollView
的对象分配给它。例如:
UIScrollViewDelegate
这样您就可以轻松实现id<UIScrollViewDelegate> originalPageScrollViewDelegate = ((UIScrollView *)[pageViewController.view.subviews objectAtIndex:0]).delegate;
[((UIScrollView *)[pageViewController.view.subviews objectAtIndex:0]) setDelegate:self];
方法。您的UIScrollViewDelegate
会调用您委托的UIPageViewController
方法。
顺便说一句,您可能不得不保留原始委托,并使用该对象响应委托方法。您可以在我的UI控件项目here
上的-scrollViewDidScroll:
类中看到示例实现
答案 5 :(得分:0)
我最近遇到了同样的事情。我的UIScrollview
处于分页模式,每个页面都包含UITableView
,就像您描述的那样有效,但并不像您预期的那样有效。这就是解决它的方法。
首先我禁用了UIScrollview
然后我为实际的UISwipeGestureRecognizer
添加了UITableView
左右滑动。
这些滑动的动作是:
[scroll setContentOffset:CGPointMake(currentPointX + 320, PointY) animated:YES];
//Or
[scroll setContentOffset:CGPointMake(currentPointX - 320 , PointY) animated:YES];
这完美无瑕,唯一的缺点是,如果用户将手指拖到UITableVIew
上,将被视为滑动。他将无法在同一屏幕上看到屏幕A的一半和屏幕B的一半。
答案 6 :(得分:0)
您可以将滚动视图和表格视图子类化,并将此手势识别器委托方法添加到每个视图中......
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:
(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
我不能确定这是完全你所追求的是什么,但它可能会接近。