如何一起滚动一组 ScrollView?
Posted
技术标签:
【中文标题】如何一起滚动一组 ScrollView?【英文标题】:How do I scroll a set of UIScrollViews together? 【发布时间】:2010-03-02 22:00:24 【问题描述】:设置:我有一个UITableView
,每个UITableViewCell
都有一个UIScrollView
。我要做的是让所有UIScrollViews
一起滚动,这样当您滚动其中一个时,所有UIScrollViews
似乎同时滚动。
我所做的是子类UITableView
,因此它的表格单元格中有一个包含所有UIScrollViews
的数组。然后我将TouchesBegan
、TouchesMoved
、TouchesCancelled
和TouchesEnded
从UITableView
转发到数组中的所有UIScrollViews
。
这似乎不起作用。 UIScrollViews
请勿滚动!我设法让它工作的唯一方法是在滚动视图上调用 setContentOffset
: 方法。然而,这是一个非常糟糕的解决方案,因为它没有为您提供UIScrollView
的滑动和减速功能。
关于为什么我的触摸方法没有到达UIScrollViews
的任何想法?或者更好的实现方式?
【问题讨论】:
【参考方案1】:好的,开始工作了。感谢 Ricki 的提示!
Ricki 解决方案中要添加的两件事,如果要避免无限循环,则必须检查是否设置了 scrollView 的 tracking 或 dragged 属性。这将确保只有实际被拖动的 ScrollView 才会调用委托。
- (void)scrollViewDidScroll:(UIScrollView *) theScrollView
if (theScrollView.dragging || theScrollView.tracking)
[self.delegate scrolling:[theScrollView contentOffSet]];
另外,在代理的滚动方法中,我将动画设置为 NO,这消除了初始滑动和其他滚动视图更新之间的延迟。
【讨论】:
不客气,很高兴你这么快就解决了问题:) 我最初的挑战与你的有点不同,但很高兴听到该解决方案也适用于其他设计。【参考方案2】:我做了一些“类似”的事情,我在父视图中嵌入了 4 个滚动视图。
我在 UIView 中放置了一个滚动视图,这个 UIView 从它的 parentView 传递了一个委托,这是跟踪所有滚动视图的视图。包含 scrollVIew 的 UIView 实现了UIScrollViewDelegate
和这个方法;
- (void)scrollViewDidScroll:(UIScrollView *) theScrollView
[self.delegate scrolling:[self.scrollView contentOffSet]];
现在父视图在所有滚动视图上都这样做了:
- (void) scrolling:(CGFloat) offset
for(UIScrollView *s in self)
[s setContentOffset:offset animated:YES];
这当然对 CPU 有点压力,但是在任何情况下滚动几个视图都会是这样:/
希望这符合您的需要,并且有意义。
添加:
在我成功之前,我走了 8 条不同的道路,经历了很多混乱。我很早就放弃了 touchBegan 方法,只是没有办法编写接近 Apple 的滑动、轻弹、滚动算法的东西。
我不知道 tableview 和 scrollview 是否会“窃取”彼此的触摸事件,但正如我从您的描述中看到的那样,您完成了这部分工作。
缓解 CPU 使用率的后续想法。将每个滚动视图添加到一个单元格,设置它的 tag=14,现在当滚动只要求所有可见单元格时,要求 viewWithTag=14,在此设置 contentOffset。全局保存内容偏移量,以便您可以将其分配给cellForRowAtIndexPath
中正在滚动到屏幕上的单元格。
所以设置offSet为全局属性,在cellForRowAtIndexPath
找到tag = 14的view,设置它的offset。这样,您甚至不需要对 scrollViews 的引用,只需要委托。
【讨论】:
啊有趣的解决方案。我回家后会试试这个。我没有想到基于scrollViewDidScroll使用setContentOffset,我是根据touches来做的。正如您可以想象的动画设置:YES 每次触摸都会造成混乱。 Ricki,很棒的建议,今晚去试试。谢谢!! 我之前几乎完全完成了这个解决方案,而且效果很好。唯一的变化是我做了动画:不。scrollViewDidScroll:
将在滚动期间被非常频繁地调用,因此其余部分无论如何都会显示为动画而无需明确设置它。这将节省一些 CPU,从而为用户提供有效的相同体验。【参考方案3】:
如果你有不同大小的 UIScrollViews 并且正在使用分页,这很好用:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)_scrollView
#pragma unused(_scrollView)
categoryPageControlIsChangingPage = NO;
for (UIImageView *iv in [categoryScrollView subviews])
iv.alpha = (iv.tag != categoryPageControl.currentPage+1)?0.5f:1.0f;
ILogPlus(@"%i %i", iv.tag, categoryPageControl.currentPage+1);
[self scrolling:_scrollView];
- (void)scrolling:(UIScrollView *)sv
CGFloat offsetX = sv.contentOffset.x;
CGFloat ratio = offsetX/sv.contentSize.width;
if ([sv isEqual:categoryScrollView])
[categoryScrollViewLarge setContentOffset:CGPointMake(ratio*categoryScrollViewLarge.contentSize.width, 0) animated:YES];
else
[categoryScrollView setContentOffset:CGPointMake(ratio*categoryScrollView.contentSize.width, 0) animated:YES];
【讨论】:
以上是关于如何一起滚动一组 ScrollView?的主要内容,如果未能解决你的问题,请参考以下文章