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

时间:2010-08-04 23:55:00

标签: iphone uiscrollview

注意:answer given here对我不起作用。

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

[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO];

理论上,给定一个已知可见的矩形,滚动将停在原处,但事实证明这没有任何效果 - 显然滚动视图看到给定的矩形在界限并且不采取任何行动。我可以让滚动停止,如果我给出一个绝对外面当前可见范围的矩形,但在视图的contentSize内。这似乎停止了预期的视图......但也导致它跳转到其他位置。我可能会在边缘做一些游戏以使其合理地工作,但有没有人知道一种干净的方法来停止正在做它的滚动视图?

感谢。

12 个答案:

答案 0 :(得分:97)

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

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

- (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];
}

[编辑]从iOS 4.3开始(可能更早),这似乎也可以正常工作

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

答案 1 :(得分:73)

实际的一般答案是,[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];

嗯,基本上是David Liu在他编辑的答案中所说的。但我想明确指出,这两个API NOT 相同。

斯威夫特3:

scrollView.setContentOffset(scrollView.contentOffset, animated: false)

答案 2 :(得分:67)

对我来说,David Lui's accepted answer above对我不起作用。这就是我最终做的事情:

- (void)killScroll {
    self.scrollView.scrollEnabled = NO;
    self.scrollView.scrollEnabled = YES;
}

对于它的价值,我使用的是iOS 6.0 iPhone模拟器。

答案 3 :(得分:16)

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

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

这会将targetContentOffset设置为scrollView的当前偏移量,从而使滚动停止,因为它已到达目标。 实际上使用一种方法是有意义的,其目的是用户可以设置目标contentOffset

夫特

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

答案 4 :(得分:15)

停止 swift

中的滚动
scrollView.setContentOffset(scrollView.contentOffset, animated: false)

答案 5 :(得分:12)

实际上......最“现代”的方式是 - &gt;

scrollview.panGestureRecognizer.enabled = false;
scrollview.panGestureRecognizer.enabled = true;

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

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

[scrollview setContentOffset: scrollview.contentOffset animated:false];

答案 6 :(得分:5)

最干净的方法是继承UIScrollView并提供自己的setContentOffset方法。如果您尚未打开freeze布尔属性,则应该在上传递消息。

像这样:

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

-(void)setContentOffset:(CGPoint)offset
{
    if ( !freeze ) [super setContentOffset:offset];
}

然后,冻结:

scrollView.freeze = YES;

答案 7 :(得分:3)

这个答案对我有用: Deactivate UIScrollView decelerating

-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
    [scrollView setContentOffset:scrollView.contentOffset animated:YES];
}

答案 8 :(得分:2)

禁用此功能只是滚动用户交互。 (迅速)

scrollView.isScrollEnabled = false

在拖动后的滚动动画期间禁用。 (迅速)

var scrollingByVelocity = false

func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
    if !scrollingByVelocity {
        scrollView.setContentOffset(scrollView.contentOffset, animated: false)
    }
}

答案 9 :(得分:0)

这在 Swift 4.2 中对我有效:

   func killScroll() {
    self.scrollView.isScrollEnabled = false;
    self.scrollView.isScrollEnabled = true;
}

...作为扩展名:

extension UIScrollView {
    func killScroll() {
        self.isScrollEnabled = false;
        self.isScrollEnabled = true;

    }
}

答案 10 :(得分:0)

我只想在滚动视图中某个UIView是触摸期间的触摸源时才禁用滚动。由于我们的视图层次结构复杂,将UIView移出UIScrollView可能需要进行大量重构。

作为一种解决方法,我向希望防止滚动的子视图中添加了一个UIPanGestureRecognizer。此UIPanGestureRecognizer将cancelsTouchesInView阻止UIScrollView的panGesture激活。

这有点“ hack”,但这是一个非常容易的更改,如果您使用的是XIB或Storyboard,则只需将平移手势拖到相关子视图中即可。

答案 11 :(得分:0)

SWift 5 +

使用扩展程序

extension UIScrollView  {
    
    func stopDecelerating() {
        let contentOffset = self.contentOffset
        self.setContentOffset(contentOffset, animated: false)
    }
}

使用

    myScrollView.stopDecelerating()
    // your stuff