如何在UIScrollView中以编程方式强制停止滚动?

Ben*_*tto 74 iphone uiscrollview

注意:这里给出答案对我不起作用.

我有一个UIScrollView(不是表视图,只是一个自定义的东西),当用户采取某些动作时,我想杀死视图内的任何滚动(拖动或减速).我试过这样做:

[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO];
Run Code Online (Sandbox Code Playgroud)

根据这个理论,给定一个已经知道可见的矩形,滚动就会停在它的位置,但事实证明这没有任何效果 - 显然滚动视图看到给定的矩形在边界和需要没有动作.我可以让滚动停止,如果我给出一个肯定在当前可见边界之外的矩形,但是在视图的contentSize内.这似乎停止了预期的视图......但也导致它跳转到其他位置.我可能会在边缘做一些游戏以使其合理地工作,但有没有人知道一种干净的方法来停止滚动视图正在做它的事情?

谢谢.

Dav*_*Liu 100

我玩了一些你原来的解决方案,这似乎工作得很好.我觉得你几乎已经拥有了它,但是你只是偏移了你过多使用的矩形,忘记了你可以直接将矩形滚动回到原来的矩形.

任何滚动操作的通用解决方案是:

- (void)killScroll 
{
    CGPoint offset = scrollView.contentOffset;
    offset.x -= 1.0;
    offset.y -= 1.0;
    [scrollView setContentOffset:offset animated:NO];
    offset.x += 1.0;
    offset.y += 1.0;
    [scrollView setContentOffset:offset animated:NO];
}
Run Code Online (Sandbox Code Playgroud)

[编辑]从iOS 4.3(可能更早)开始,这似乎也有效

- (void)killScroll 
{
    CGPoint offset = scrollView.contentOffset;
    [scrollView setContentOffset:offset animated:NO];
}
Run Code Online (Sandbox Code Playgroud)

  • 在iOS 7中,当scrollView isDecelerating时,只有顶级解决方案有效(+ = 1, - = 1解决方案). (2认同)

cal*_*kus 77

实际的一般答案是,这[scrollView setContentOffset:offset animated:NO]不一样[scrollView setContentOffset:offset]!

  • [scrollView setContentOffset:offset animated:NO] 实际上停止任何运行动画.
  • [scrollView setContentOffset:offset] 不会停止任何正在运行的动画.
  • 相同scrollView.contentOffset = offset:不会停止任何正在运行的动画.

这在任何地方都没有记录,但这是在iOS 6.1和iOS 7.1上测试的行为 - 可能也是之前.

所以停止正在运行的动画/减速的解决方案很简单:

[scrollView setContentOffset:scrollView.contentOffset animated:NO];
Run Code Online (Sandbox Code Playgroud)

嗯,基本上是David Liu在他编辑的答案中所说的.但我想说清楚,这两个API 并不相同.

斯威夫特3:

scrollView.setContentOffset(scrollView.contentOffset, animated: false)
Run Code Online (Sandbox Code Playgroud)

  • 我们之间对"理性寻求者"的解释做得很好......(: (11认同)
  • 这有点让我伤心. (3认同)
  • 我不明白为什么这些东西没有记录...... urggggghh (2认同)

TPo*_*hel 68

对我来说,David Lui上面接受的答案对我不起作用.这就是我最终做的事情:

- (void)killScroll {
    self.scrollView.scrollEnabled = NO;
    self.scrollView.scrollEnabled = YES;
}
Run Code Online (Sandbox Code Playgroud)

值得一提的是,我正在使用iOS 6.0 iPhone模拟器.

  • 像你说的+1,另一个对我来说也不起作用,但这个解决方案效果很好! (2认同)

fun*_*ct7 17

这是我为滚动视图和所有其他相关子类所做的事情:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
 {
    *targetContentOffset = scrollView.contentOffset;
 }
Run Code Online (Sandbox Code Playgroud)

这台targetContentOffsetscrollView目前的偏移,从而使滚动停止,因为它已经达到了目标.实际上使用一个方法是有意义的,其目的是用户可以设置目标contentOffset.

迅速

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    targetContentOffset.pointee = scrollView.contentOffset
}
Run Code Online (Sandbox Code Playgroud)


bud*_*ino 17

swift中停止滚动:

scrollView.setContentOffset(scrollView.contentOffset, animated: false)
Run Code Online (Sandbox Code Playgroud)


Xat*_*ian 13

实际上......最"现代"的方式是 - >

scrollview.panGestureRecognizer.enabled = false;
scrollview.panGestureRecognizer.enabled = true;
Run Code Online (Sandbox Code Playgroud)

这将停用手势识别器,该手势识别器负责滚动片刻,这将消除当前触摸.用户需要抬起手指并将其放回以开始再次滚动.

编辑:这实际上只是杀死用户的当前拖动,但如果当前滚动视图处于此状态,则不会立即停止减速.要做到这一点,接受的答案编辑几乎是xD的最佳方式

[scrollview setContentOffset: scrollview.contentOffset animated:false];
Run Code Online (Sandbox Code Playgroud)


mvd*_*vds 5

最干净的方法是继承UIScrollView并提供自己的setContentOffset方法.只有在您没有打开freeze布尔属性时,应该传递消息.

像这样:

BOOL freeze; // and the @property, @synthesize lines..

-(void)setContentOffset:(CGPoint)offset
{
    if ( !freeze ) [super setContentOffset:offset];
}
Run Code Online (Sandbox Code Playgroud)

然后,冻结:

scrollView.freeze = YES;
Run Code Online (Sandbox Code Playgroud)