2010-10-15 139 views
37

这很奇怪,我想知道如果有人有任何想法?问题与uiscrollview setcontentoffset动画不滚动时动画:是设置

我想滚动一个UIScrollView作为回应在iPad上按下按钮。

如果我做的:

CGPoint currentOff = scrollView.contentOffset; 
currentOff.x+=240; 
[scrollView setContentOffset:currentOff animated: NO]; 

滚动视图跳到预期需要的位置,但我想它滚动。但是,当我这样做:

CGPoint currentOff = scrollView.contentOffset; 
currentOff.x+=240; 
[scrollView setContentOffset:currentOff animated: YES]; 

然后它什么也没做!我有另一个正常工作的滚动视图,并按预期回应setContentOffset:YES,所以我感到很困惑。任何关于为什么滚动可能不会发生的想法是非常值得欢迎的!

另外,当使用animated:YES时,- (void)scrollViewDidScroll:(UIScrollView *)sender没有收到任何东西,但在使用animated:NO时被调用!

+2

嗯,我看到一些非常相似的东西。 setContentOffset和scrollRectToVisible都可以按照预期使用animated = false,但对animated = true无效。也好奇,如果我用我的手指拖动scrollView一下,然后再次尝试按钮,它的工作原理。我已经打印了scrollView的contentSize,它看起来是正确的。 – 2011-08-23 23:19:54

+0

有趣的是,我只是有同样的问题,但倒过来。它只在我为它制作动画时才起作用。 – 2013-09-16 13:46:54

+1

嗨。看看我的答案在http://stackoverflow.com/a/27088865/1510171 – tomeron11 2014-11-23 12:24:37

回答

72

我过这种情况也是一样,结束了这样的解决方法:获取调用多次动画有机会运行前:

[UIView animateWithDuration:.25 animations:^{ 
    self.scrollView.contentOffset = ...; 
}]; 
+2

我有同样的问题,这种解决方法也为我工作!谢谢! – 2012-10-12 12:23:54

+0

你能解释一下可能是什么原因(对于setContentOffset:animated:不工作,并以这种方式工作) – Tatvamasi 2012-12-11 08:59:41

+2

我不确定,我认为这是一个错误,动画版本不起作用。 – 2012-12-12 20:09:47

0

你可以尝试:

[scrollView setContentOffset:CGPointMake(240, 0) animated:YES]; 
2

很难用这段代码你给说了。事实上,如果你说,你有一个项目,在一切工作在相同的条件下,那么显然条件是不一样的:)我不能重现这个问题,但这里有一些假设2种情况:

  1. 用nib创建UIScrollView。

    • 只是不要忘记创建IBOutlet并将其绑定到nib中的scrollView元素。在一个基于简单视图的应用程序之后,我得到了scrollView的动画效果:YES和NO。但是,为了使工作

    -(void)scrollViewDidScroll:(UIScrollView *)sender;必须设置委托:

yourScrollView.delegate = self;

其中 '自我' 是类,其中有您的scrollViewDidScroll功能;顺便说一句,这个类必须符合'UIScrollViewDelegate'协议。

2.手动创建UIScrollView对象。

  • 这里的想法是基本相同的,所以我就提供一些简单的代码:

    -(void) creatingScrollView { 
        UIScrollView *newScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 5, 280, 44)]; 
        newScroll.pagingEnabled = YES; 
        newScroll.showsVerticalScrollIndicator = NO; 
        newScroll.showsHorizontalScrollIndicator = NO; 
    
        // ... some subviews being added to our scroll view 
    
        newScroll.delegate = self; 
        [self.view addSubview:newScroll]; 
        [newScroll release]; 
    } 
    

这对我的作品。希望这是有帮助的。

7

从个人的经验来说,当setContentOffset出现此问题。

我还没有完全找到了这个问题,但我相信这个问题是这样的:

setContentOffset:动画被调用这台新的偏移值。 setContentOffset:随后用相同的参数调用,取消动画。它还注意到新参数与旧参数相同,因此即使动画还没有运行,也不需要做任何事情。

上面的解决方案以某种方式打破了这个循环,但也许更少的解决方法是在代码中放置断点并消除多个调用。

+0

这个解释帮助我解决了类似的问题。谢谢! – chadbag 2014-01-29 18:07:12

+1

我的修复是在'setContentOffset:animated'之后移除对'setNeedsLayout'的调用。 – 2015-03-25 00:29:59

+0

嗯,什么是“上面的解决方案”,大声笑? makaron的解决方案? – Harris 2016-02-24 20:06:07

0

我面临同样的问题,滚动视图不滚动。 而且我禁用视图上的“使用自动布局”,然后ScrollView工作。

0

我有同样的问题,在我的情况我也被拦截:

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {...} 

此方法后,立即叫: (它不会等到动画结束):

[scrollView setContentOffset:currentOff animated: YES]; 

这意味着如果你有任何逻辑“等待”动画的结尾,并且你截取了scrollViewDidEndScrollingAnimation,那么结果将是未定义的,IE:提前结束动画。

编辑:接受的解决方案/解决方法:

[UIView animateWithDuration:.25 animations:^{ 
    self.scrollView.contentOffset = ...; 
}]; 

而且 “作品” 在我的情况,因为设置contentOffset直接不调用scrollViewDidEndScrollingAnimation

1

解决方案Xamarin.iOS

InvokeOnMainThread(() => 
{ 
    scrollView.SetContentOffset(new PointF((page * UIScreen.MainScreen.Bounds.Width), 0), true); 
}); 

这也可以使用UIView.Animate

来解决
UIView.Animate(
    duration: .25, 
    animation:() => 
    { 
     scrollView.SetContentOffset(new PointF((value * UIScreen.MainScreen.Bounds.Width), 0), true); 
    } 
); 
+0

当您使用自定义动画('UIView.Animate')时,不应该使用'animated' * false * – testing 2015-04-07 12:08:46

0
func scrollViewDidScroll(scrollView: UIScrollView) { 

    dispatch_async(dispatch_get_main_queue(),{ 

     UIView.animateWithDuration(0.10, animations: {() -> Void in 

      let loginScrollViewCurrentPosition:CGPoint = CGPointMake(self.loginScrollView.contentOffset.x, self.loginScrollView.contentOffset.y) as CGPoint 
      self.loginScrollView.setContentOffset(loginScrollViewCurrentPosition, animated: true) 

      }) 
    }) 

}