如何让两个滚动视图彼此滚动?
例如,我在屏幕的左侧有一个滚动视图(A),它的内容可以上下滚动,但不能左右滚动。滚动视图B匹配A的上下滚动,但也可以向左和向右滚动。滚动视图A始终显示在屏幕上。
-----------------------------------------------------------
| | |
| | |
| | |
| A | B |
| | |
| scrolls | |
| up & down | scrolls all directions |
| | |
-----------------------------------------------------------
我如何才能使(两个视图的)向上和向下滚动也使另一个视图在相同的向上-向下方向滚动?或者有其他方法可以做到这一点?
发布于 2017-10-30 17:32:26
我在iOS 11上尝试了西蒙·李的答案。它工作得很好,但不是很好。两个滚动视图是同步的,但使用他的方法,滚动视图将失去惯性效果(当您松开手指后继续滚动时)和反弹效果。我认为这是因为通过setContentOffset(offset, animated: false)
方法设置contentOffset
会导致循环调用scrollViewDidScroll(_ scrollView: UIScrollView)
委托的方法(请参阅this question)
以下是我在iOS 11上使用的解决方案:
// 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)
不会被循环调用,滚动发生得非常流畅,具有惯性和弹跳效果,就像单个滚动视图一样。
发布于 2020-05-21 14:15:16
伙计们,我知道这个问题已经得到了回答,但我决定在这里与你们分享我解决类似问题的方法,因为我相信这是一个相当干净的解决方案。基本上,我必须让三个集合视图一起滚动,我所做的是做了一个custom UICollectionView
subclass called SharedOffsetCollectionView
,当你在故事板中将这个类设置为一个集合视图,或者你直接从代码中实例化它时,你可以让所有的实例滚动相同。
因此,使用SharedOffsetCollectionView
时,应用程序中此类的所有集合视图实例都将始终滚动。在我看来,这是一个干净的解决方案,因为它需要在视图控制器中添加零逻辑,所有这些都包含在这个外部类中,您只需将集合视图的类设置为SharedOffsetCollectionView
,就完成了。
同样的方法可以很容易地转移到UITableView
和UIScrollView
希望这能对你有所帮助。:)
我的解决方案是这样写的:
Swift 5.2,XCode 11.4.1
发布于 2021-04-14 23:08:15
上面的答案对我来说并不是很有效,因为我遇到了scrollViewDidScroll
的循环调用。这种情况会发生,因为设置滚动视图的内容偏移量也会调用scrollViewDidScoll
。我通过在它之间设置一个锁来解决这个问题,这个锁是根据用户是否正在拖动滚动视图来设置的,所以同步不会通过设置内容偏移量来发生:
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)
}
这段代码可以根据使用的滚动视图数量和拥有它们的人进行重构。我不推荐将一个控制器作为许多滚动视图的代理。我宁愿用委派来解决它。
https://stackoverflow.com/questions/7918481
复制相似问题