注意:answer given here对我不起作用。
我有一个UIScrollView(不是表格视图,只是一个自定义的东西),当用户采取某些动作时,我想杀死视图内的任何滚动(拖动或减速)。我试过做过例如这样:
[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO];
理论上,给定一个已知可见的矩形,滚动将停在原处,但事实证明这没有任何效果 - 显然滚动视图看到给定的矩形在界限并且不采取任何行动。我可以让滚动停止,如果我给出一个绝对在外面当前可见范围的矩形,但在视图的contentSize内。这似乎停止了预期的视图......但也导致它跳转到其他位置。我可能会在边缘做一些游戏以使其合理地工作,但有没有人知道一种干净的方法来停止正在做它的滚动视图?
感谢。
答案 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