如何一起滚动一组 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 的数组。然后我将TouchesBeganTouchesMovedTouchesCancelledTouchesEndedUITableView 转发到数组中的所有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?的主要内容,如果未能解决你的问题,请参考以下文章

ScrollView与ListView的冲突

iOS 上的 Pinterest Gridview 实现

mas 中scrollview碰到的问题。ios10.0后

可滚动UIStackView 竖向居中 / 横向右对齐

如何在ScrollView中嵌套ListView

SwiftUI - ScrollView 没有一直滚动到底部