can*_*boy 18 iphone objective-c uiscrollview ios
如何使两个滚动视图跟随彼此滚动?
例如,我在屏幕左侧有一个滚动视图(A),其内容可以向上和向下滚动,但不能向左和向右滚动.滚动视图B匹配A的上下,但也可以左右滚动.滚动视图A始终在屏幕上.
-----------------------------------------------------------
| | |
| | |
| | |
| A | B |
| | |
| scrolls | |
| up & down | scrolls all directions |
| | |
-----------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
我如何制作它以使上下滚动(任一视图)也使另一个视图在相同的上下方向滚动?或者还有另一种方法吗?
Sim*_*Lee 42
将滚动视图A的代理设置为视图控制器...然后...
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint offset = scrollViewB.contentOffset;
offset.y = scrollViewA.contentOffset.y;
[scrollViewB setContentOffset:offset];
}
Run Code Online (Sandbox Code Playgroud)
如果你想两者互相关注,那么为它们设置委托并使用......
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if([scrollView isEqual:scrollViewA]) {
CGPoint offset = scrollViewB.contentOffset;
offset.y = scrollViewA.contentOffset.y;
[scrollViewB setContentOffset:offset];
} else {
CGPoint offset = scrollViewA.contentOffset;
offset.y = scrollViewB.contentOffset.y;
[scrollViewA setContentOffset:offset];
}
}
Run Code Online (Sandbox Code Playgroud)
以上可以重构为具有两个滚动视图并且彼此匹配的方法.
- (void)matchScrollView:(UIScrollView *)first toScrollView:(UIScrollView *)second {
CGPoint offset = first.contentOffset;
offset.y = second.contentOffset.y;
[first setContentOffset:offset];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if([scrollView isEqual:scrollViewA]) {
[self matchScrollView:scrollViewB toScrollView:scrollViewA];
} else {
[self matchScrollView:scrollViewA toScrollView:scrollViewB];
}
}
Run Code Online (Sandbox Code Playgroud)
Swift 3版本:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == scrollViewA {
self.synchronizeScrollView(scrollViewB, toScrollView: scrollViewA)
}
else if scrollView == scrollViewB {
self.synchronizeScrollView(scrollViewA, toScrollView: scrollViewB)
}
}
func synchronizeScrollView(_ scrollViewToScroll: UIScrollView, toScrollView scrolledView: UIScrollView) {
var offset = scrollViewToScroll.contentOffset
offset.y = scrolledView.contentOffset.y
scrollViewToScroll.setContentOffset(offset, animated: false)
}
Run Code Online (Sandbox Code Playgroud)
我在iOS 11上试过了Simon Lee的答案.但是效果不是很好.两个滚动视图已同步,但使用他的方法,滚动视图将失去惯性效果(当您释放手指后继续滚动)和弹跳效果.我认为这是因为设置contentOffset
through setContentOffset(offset, animated: false)
方法会导致scrollViewDidScroll(_ scrollView: UIScrollView)
委托方法的循环调用(请参阅此问题)
以下是适用于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
}
Run Code Online (Sandbox Code Playgroud)
因此,不是设置contentOffset
我们使用bounds
属性来同步其他scrollView与用户滚动的滚动视图.这种方式scrollViewDidScroll(_ scrollView: UIScrollView)
不会循环调用委托方法,并且滚动发生得非常平滑,并且具有惯性和弹跳效果,就像单个滚动视图一样.
斯威夫特 5.4 // Xcode 13.1
对我来说完美无缺的工作如下:
UIGestureRecognizer
委托gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:)
GestureRecognizerDelegate
方法public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
Run Code Online (Sandbox Code Playgroud)
yourSuperview.addGestureRecognizer(scrollView1.panGestureRecognizer)
yourSuperview.addGestureRecognizer(scrollView2.panGestureRecognizer)
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
归档时间: |
|
查看次数: |
12614 次 |
最近记录: |