代码之家  ›  专栏  ›  技术社区  ›  sushibrain

使多个ScrollView在一个显示滚动行为时作出响应

  •  0
  • sushibrain  · 技术社区  · 7 年前

    我有一个视图,里面有四个滚动视图。我想做的是,当其中一个滚动时,让所有这些滚动视图都响应。我试图通过以下代码做到这一点:

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
            self.hpcScrollView.setContentOffset(scrollView.contentOffset, animated: true)
            self.parScrollView.setContentOffset(scrollView.contentOffset, animated: true)
            self.scoreScrollView.setContentOffset(scrollView.contentOffset, animated: true)
            self.holeScrollView.setContentOffset(scrollView.contentOffset, animated: true)
    }
    

    然而,当我应用这个时,滚动的“行为”就消失了。它仍在滚动,但没有反弹,当我将手指从滚动视图上取下时,它立即停止滚动(参见下面的gif)

    enter image description here

    有没有办法让这感觉像是正常的滚动?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Sam    7 年前

    不要应用 contentOffset 到当前正在滚动的scrollView。更改 内容偏移量 在当前滚动视图上,将导致其停止滚动并立即跳转到偏移量。

    let scrollableViews = [hpcScrollView, parScrollView, scoreScrollView, holeScrollView]    
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        scrollableViews.forEach { if $0 != scrollView { $0.setContentOffset(scrollView.contentOffset, animated: true) } }
    }
    

    编辑:

    这个 scrollViewDidScroll 每当我们设置内容偏移量时都会调用,这会导致gif中显示的奇怪滚动行为。

    试试这个

    let scrollableViews = [hpcScrollView, parScrollView, scoreScrollView, holeScrollView]    
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        scrollableViews.forEach { if $0 != scrollView {
            let scrollBounds = $0.bounds
            scrollBounds.origin = scrollView.contentOffset
            $0.bounds = scrollBounds
        } }
    }
    
        2
  •  1
  •   LGP    7 年前

    问题是您重置了原始滚动视图,从而使其停止。您需要跟踪用户正在交互的当前滚动视图,并且只更新其他滚动视图。否则,它们都将生成滚动事件并最终相互更新。

    // currentScrollView is an object var
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        currentScrollView = scrollView
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView == currentScrollView {
            if currentScrollView != self.hpcScrollView {
                self.hpcScrollView.setContentOffset(scrollView.contentOffset, animated: false)
            }
            if currentScrollView != self.parScrollView {
                self.parScrollView.setContentOffset(scrollView.contentOffset, animated: false)
            }
            if currentScrollView != self.scoreScrollView {
                self.scoreScrollView.setContentOffset(scrollView.contentOffset, animated: false)
            }
            if currentScrollView != self.holeScrollView {
                self.holeScrollView.setContentOffset(scrollView.contentOffset, animated: false)
            }
        }
    }
    

    请注意,您必须设置 animated 标志到 false .