首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >让两个UIScrollViews相互跟随滚动

让两个UIScrollViews相互跟随滚动
EN

Stack Overflow用户
提问于 2011-10-27 23:38:27
回答 3查看 17.1K关注 0票数 24

如何让两个滚动视图彼此滚动?

例如,我在屏幕的左侧有一个滚动视图(A),它的内容可以上下滚动,但不能左右滚动。滚动视图B匹配A的上下滚动,但也可以向左和向右滚动。滚动视图A始终显示在屏幕上。

代码语言:javascript
复制
-----------------------------------------------------------
|             |                                           |
|             |                                           |
|             |                                           |
|     A       |                    B                      |
|             |                                           |
|    scrolls  |                                           |
|   up & down |              scrolls all directions       |
|             |                                           |
-----------------------------------------------------------

我如何才能使(两个视图的)向上和向下滚动也使另一个视图在相同的向上-向下方向滚动?或者有其他方法可以做到这一点?

EN

回答 3

Stack Overflow用户

发布于 2017-10-30 17:32:26

我在iOS 11上尝试了西蒙·李的答案。它工作得很好,但不是很好。两个滚动视图是同步的,但使用他的方法,滚动视图将失去惯性效果(当您松开手指后继续滚动时)和反弹效果。我认为这是因为通过setContentOffset(offset, animated: false)方法设置contentOffset会导致循环调用scrollViewDidScroll(_ scrollView: UIScrollView)委托的方法(请参阅this question)

以下是我在iOS 11上使用的解决方案:

代码语言:javascript
复制
 // implement UIScrollViewDelegate method
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if scrollView == self.scrollViewA {
            self.syncScrollView(self.scrollViewB, toScrollView: self.scrollViewA)
        }
        else if scrollView == self.scrollViewB {
            self.syncScrollView(self.scrollViewA, toScrollView: scrollViewB)
        }
    }

    func syncScrollView(_ scrollViewToScroll: UIScrollView, toScrollView scrolledView: UIScrollView) {
        var scrollBounds = scrollViewToScroll.bounds
        scrollBounds.origin.y = scrolledView.contentOffset.y
        scrollViewToScroll.bounds = scrollBounds
    }

因此,我们使用bounds属性来同步另一个scrollView和用户滚动的那个,而不是设置contentOffset。这样,委托方法scrollViewDidScroll(_ scrollView: UIScrollView)不会被循环调用,滚动发生得非常流畅,具有惯性和弹跳效果,就像单个滚动视图一样。

票数 16
EN

Stack Overflow用户

发布于 2020-05-21 14:15:16

伙计们,我知道这个问题已经得到了回答,但我决定在这里与你们分享我解决类似问题的方法,因为我相信这是一个相当干净的解决方案。基本上,我必须让三个集合视图一起滚动,我所做的是做了一个custom UICollectionView subclass called SharedOffsetCollectionView,当你在故事板中将这个类设置为一个集合视图,或者你直接从代码中实例化它时,你可以让所有的实例滚动相同。

因此,使用SharedOffsetCollectionView时,应用程序中此类的所有集合视图实例都将始终滚动。在我看来,这是一个干净的解决方案,因为它需要在视图控制器中添加零逻辑,所有这些都包含在这个外部类中,您只需将集合视图的类设置为SharedOffsetCollectionView,就完成了。

同样的方法可以很容易地转移到UITableViewUIScrollView

希望这能对你有所帮助。:)

我的解决方案是这样写的:

Swift 5.2,XCode 11.4.1

票数 2
EN

Stack Overflow用户

发布于 2021-04-14 23:08:15

上面的答案对我来说并不是很有效,因为我遇到了scrollViewDidScroll的循环调用。这种情况会发生,因为设置滚动视图的内容偏移量也会调用scrollViewDidScoll。我通过在它之间设置一个锁来解决这个问题,这个锁是根据用户是否正在拖动滚动视图来设置的,所以同步不会通过设置内容偏移量来发生:

代码语言:javascript
复制
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    self.synchronizeScrollView(offSet: scrollView.contentOffset.y,
                               scrollViewAIsScrolling: scrollView == scrollViewA,
                               isScroller: scrollView.isDragging)
}

private enum Scroller {
    case page, time
}

private var scroller: Scroller? = nil

func synchronizeScrollView(offSet: CGFloat, scrollViewAIsScrolling: Bool,
                           isScroller: scrollView.isDragging) {
    
    let scrollViewToScroll = scrollViewAIsScrolling ? scrollViewB : scrollViewA
    var offset = scrollViewToScroll.contentOffset
    offset.y = offSet
    scrollViewToScroll.setContentOffset(offset, animated: false)
}

这段代码可以根据使用的滚动视图数量和拥有它们的人进行重构。我不推荐将一个控制器作为许多滚动视图的代理。我宁愿用委派来解决它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7918481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档