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

DBD*_*DBD 60 uiscrollview uiscrollviewdelegate ios

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

我使用UIScrollViewDelegatescrollViewDidScroll:跟踪运动.我查询contentOffsetUIScrollView哪些改变,然后反映他们的设置更改为其他滚动视图contentOffset属性相匹配.

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

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

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

Tar*_*ark 106

通过将原点设置的边界设置为所需的内容偏移量,可以在UIScrollView不触发委托回调的情况下更改a的内容偏移量.scrollViewDidScroll:UIScrollView

CGRect scrollBounds = scrollView.bounds;
scrollBounds.origin = desiredContentOffset;
scrollView.bounds = scrollBounds;
Run Code Online (Sandbox Code Playgroud)

  • 上述评论者都喜欢这个答案,但都没有给他一个向上箭头.你们羞耻!我需要这些信息,只是发现了它,但我给了他一个观点. (7认同)
  • 这仍然会再次调用scrollViewDidScroll,但直到当前的scrollViewDidScroll函数结束后才会这样做. (4认同)
  • 为什么我的男人如此冷漠?它是真正的所有内容偏移,并且可以使用UIView动画块和东西进行动画制作. (2认同)

小智 78

尝试

id scrollDelegate = scrollView.delegate;
scrollView.delegate = nil;
scrollView.contentOffset = point;
scrollView.delegate = scrollDelegate;
Run Code Online (Sandbox Code Playgroud)

为我工作.

  • 简单而富有创意.爱它. (3认同)

Kuk*_*osk 41

使用UIScrollView的现有属性怎么样?

if(scrollView.isTracking || scrollView.isDragging || scrollView.isDecelerating) {
    //your code
}
Run Code Online (Sandbox Code Playgroud)

  • @DBD - 如果你担心UIKit中的每个API都在变化,我不知道你会怎么做.依赖公开记录的API并不脆弱. (6认同)
  • 到目前为止,这里有最佳答案.与边界解决方案不同,它不是一些神秘的副作用,绝对可能随着未来的行为而改变,并且除非引入新的触摸交互类型,否则引入新概念的滚动视图的可能性非常低 - 让我们面对它,10年进入iOS(我们现在甚至通过强制触摸)极不可能发生.如果它确实...大呐喊,再为你的代码添加一个交互,你就完成了.甚至可以将其旋转到一个扩展名(使用'ieUserInteracting'属性)并一次处理所有滚动视图.完成. (6认同)

Sim*_*lGy 6

简化@Tark的答案,你可以定位滚动视图,而不是scrollViewDidScroll像这样在一行中触发:

scrollView.bounds.origin = CGPoint(x:0, y:100); // whatever values you'd like
Run Code Online (Sandbox Code Playgroud)


小智 5

另一种方法是在scrollViewDidScroll委托中添加一些逻辑,以确定是以编程方式还是通过用户的触摸来触发内容偏移的更改.

  • 在您的类中添加'isManualScroll'布尔变量.
  • 将其初始值设置为false.
  • 在scrollViewWillBeginDragging中将其设置为true.
  • 在你的scrollViewDidScroll中检查它是否为真,只在它响应时才响应.
  • 在scrollViewDidEndDecelerating中将其设置为false.
  • 在scrollViewWillEndDragging中,如果velocity为0,则添加逻辑以将其设置为false(因为在这种情况下不会调用scrollViewDidEndDecelerating).