我在页面上有一些UIScrollView
。您可以单独滚动它们或将它们锁定在一起并将它们滚动为一个。锁定时会出现问题。
我使用UIScrollViewDelegate
和scrollViewDidScroll:
来跟踪移动。我查询已更改的contentOffset
的{{1}},然后通过将其UIScrollView
属性设置为匹配来反映对其他滚动视图的更改。
很棒....除了我注意到很多额外的电话。以编程方式更改滚动视图的contentOffset
会触发调用委托方法contentOffset
。我尝试使用scrollViewDidScroll:
,但我仍然在委托上获得触发器。
如何以编程方式修改contentOffsets以不触发setContentOffset:animated:
?
实施说明....
每个scrollViewDidScroll:
都是自定义UIScrollView
的一部分,它使用委托模式回调到处理协调各种UIView
值的呈现UIViewController
子类。
答案 0 :(得分:105)
通过设置UIScrollView
的边界并将原点设置为所需的内容偏移量,可以更改scrollViewDidScroll:
的内容偏移而不触发委托回调UIScrollView
。
CGRect scrollBounds = scrollView.bounds;
scrollBounds.origin = desiredContentOffset;
scrollView.bounds = scrollBounds;
答案 1 :(得分:74)
尝试
id scrollDelegate = scrollView.delegate;
scrollView.delegate = nil;
scrollView.contentOffset = point;
scrollView.delegate = scrollDelegate;
为我工作。
答案 2 :(得分:37)
如何使用UIScrollView的现有属性?
if(scrollView.isTracking || scrollView.isDragging || scrollView.isDecelerating) {
//your code
}
答案 3 :(得分:6)
简化@Tark的回答,你可以定位滚动视图,而不会像这样在一行中触发scrollViewDidScroll
:
scrollView.bounds.origin = CGPoint(x:0, y:100); // whatever values you'd like
答案 4 :(得分:5)
另一种方法是在scrollViewDidScroll委托中添加一些逻辑,以确定是以编程方式还是通过用户的触摸来触发内容偏移的更改。
答案 5 :(得分:4)
这不是这个问题的直接答案,但是如果你得到看似虚假的信息,那也可能是因为你正在改变界限。我正在使用一些带有“tilePages”方法的Apple示例代码,该方法将子视图删除并添加到滚动视图中。这很少导致额外的scrollViewDidScroll:立即调用的消息,所以你进入一个你肯定没想到的递归。在我的情况下,我找到一个令人讨厌的不可能找到崩溃。
我最终做的是在主队列上排队呼叫:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if(scrollView == yourScrollView) {
// dispatch fixes some recursive call to scrollViewDidScroll in tilePages (related to removeFromSuperView)
// The reason can be found here: http://stackoverflow.com/questions/9418311
dispatch_async(dispatch_get_main_queue(), ^{ [self tilePages]; });
}
}