【问题标题】:How do I scroll a set of UIScrollViews together?如何一起滚动一组 ScrollView?
【发布时间】:2010-03-02 22:00:24
【问题描述】:

设置:我有一个UITableView,每个UITableViewCell 都有一个UIScrollView。我要做的是让所有UIScrollViews 一起滚动,这样当您滚动其中一个时,所有UIScrollViews 似乎同时滚动。

我所做的是子类UITableView,因此它的表格单元格中有一个包含所有UIScrollViews 的数组。然后我将TouchesBeganTouchesMovedTouchesCancelledTouchesEndedUITableView 转发到数组中的所有UIScrollViews

这似乎不起作用。 UIScrollViews 请勿滚动!我设法让它工作的唯一方法是在滚动视图上调用 setContentOffset: 方法。然而,这是一个非常糟糕的解决方案,因为它没有为您提供UIScrollView 的滑动和减速功能。

关于为什么我的触摸方法没有到达UIScrollViews 的任何想法?或者更好的实现方式?

【问题讨论】:

    标签: iphone cocoa-touch uitableview uiscrollview


    【解决方案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];
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多