设置contentOffset以编程方式触发scrollViewDidScroll

我在页面上有几个UIScrollView 。 您可以独立滚动它们或将它们locking在一起并将它们作为一个滚动。 locking时发生问题。

我使用UIScrollViewDelegatescrollViewDidScroll:来跟踪移动。 我查询了UIScrollViewcontentOffset ,它更改了内容,然后通过设置其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)。