设置contentOffset以编程方式触发scrollViewDidScroll
我在页面上有几个UIScrollView
。 您可以独立滚动它们或将它们locking在一起并将它们作为一个滚动。 locking时发生问题。
我使用UIScrollViewDelegate
和scrollViewDidScroll:
来跟踪移动。 我查询了UIScrollView
的contentOffset
,它更改了内容,然后通过设置其contentOffset
属性来匹配其他滚动视图。
伟大的….除了我注意到很多额外的电话。 以编程方式更改我的滚动视图的contentOffset
触发委托方法scrollViewDidScroll:
被调用。 我试过使用setContentOffset:animated:
相反,但我仍然得到委托的触发器。
我如何修改我的contentOffsets以编程方式不触发scrollViewDidScroll:
实现说明….每个UIScrollView
是自定义UIView
一部分,它使用委托模式来callback处理协调各种contentOffset
值的呈现UIViewController
子类。
可以在不触发委托callbackscrollViewDidScroll:
情况下更改UIScrollView
的内容偏移scrollViewDidScroll:
通过将UIScrollView
的边界设置为所需的内容偏移量。
CGRect scrollBounds = scrollView.bounds; scrollBounds.origin = desiredContentOffset; scrollView.bounds = scrollBounds;
尝试
id scrollDelegate = scrollView.delegate; scrollView.delegate = nil; scrollView.contentOffset = point; scrollView.delegate = scrollDelegate;
为我工作。
那么使用UIScrollView的现有属性呢?
if(scrollView.isTracking || scrollView.isDragging || scrollView.isDecelerating) { //your code }
简化@Tark的答案,你可以在不使用scrollViewDidScroll的情况下定位scrollViewDidScroll
,如下所示:
scrollView.bounds.origin = CGPoint(x:0, y:100); // whatever values you'd like
这不是对这个问题的直接回答,但是如果你得到似乎是虚假的这样的信息,也可能是因为你正在改变界限。 我正在使用一些“tilePages”方法的Apple示例代码,该方法删除子视图并将其添加到滚动视图。 这很less会导致额外的scrollViewDidScroll:消息立即调用,所以你进入了一个你肯定没有想到的recursion。 在我的情况下,我有一个讨厌的不可能find崩溃。
我最终做的是在主队排队:
- (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]; }); } }
另一种方法是在您的scrollViewDidScroll委托中添加一些逻辑,以确定是否以编程方式或通过用户的触摸来触发内容偏移的更改。
- 将“isManualScroll”布尔variables添加到您的class级。
- 将其初始值设置为false。
- 在scrollViewWillBeginDragging中将其设置为true。
- 在您的scrollViewDidScroll检查,看看是否是真的,只有如果它是响应。
- 在scrollViewDidEndDecelerating中将其设置为false。
- 在scrollViewWillEndDragging中添加逻辑,如果速度为0,则将其设置为false(因为在这种情况下不会调用scrollViewDidEndDecelerating)。