以编程方式设置contentOffset会触发scrollViewDidScroll

时间:2012-02-23 17:45:29

标签: ios uiscrollview uiscrollviewdelegate

我在页面上有一些UIScrollView。您可以单独滚动它们或将它们锁定在一起并将它们滚动为一个。锁定时会出现问题。

我使用UIScrollViewDelegatescrollViewDidScroll:来跟踪移动。我查询已更改的contentOffset的{​​{1}},然后通过将其UIScrollView属性设置为匹配来反映对其他滚动视图的更改。

很棒....除了我注意到很多额外的电话。以编程方式更改滚动视图的contentOffset会触发调用委托方法contentOffset。我尝试使用scrollViewDidScroll:,但我仍然在委托上获得触发器。

如何以编程方式修改contentOffsets以不触发setContentOffset:animated:

实施说明.... 每个scrollViewDidScroll:都是自定义UIScrollView的一部分,它使用委托模式回调到处理协调各种UIView值的呈现UIViewController子类。

6 个答案:

答案 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委托中添加一些逻辑,以确定是以编程方式还是通过用户的触摸来触发内容偏移的更改。

  • 在您的班级中添加'isManualScroll'布尔变量。
  • 将其初始值设为false。
  • 在scrollViewWillBeginDragging中将其设置为true。
  • 在你的scrollViewDidScroll中检查是否为真,只有在回复时才会回复。
  • 在scrollViewDidEndDecelerating中将其设置为false。
  • 在scrollViewWillEndDragging中添加逻辑,如果速度为0,则将其设置为false(因为在这种情况下不会调用scrollViewDidEndDecelerating)。

答案 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]; });
    }
}