我有一个UIScrollView的子类,我用它来进行图像幻灯片放映,无限滚动和圆形幻灯片放映。
我曾经以这种方式为转换设置动画:(因为我希望转换更慢)
[UIView animateWithDuration:1.0
delay:0 options:(UIViewAnimationCurveEaseOut)
animations:^{
self.scrollView.contentOffset = newOffset;}
completion:NULL];
它运作得很好。
然后我观看了WWDC 2011的“高级滚动技术”讲座,他们建议通过覆盖layoutSubviews
来实现无限滚动。
所以我改变了我的实现并覆盖了layoutSubviews
一旦我这样做,过渡动画就停止了工作。
如果我注释掉我的自定义layoutSubviews - 它再次正常工作!
为什么?
在覆盖layoutSubviews时,如何制作自己的滚动动画?
谢谢!
答案 0 :(得分:3)
好的,我想我发现了问题,并且可能已经解决了。
理解问题的关键是了解当你打电话时
[UIView animateWithDuration...]
您在动画块中更改的所有属性都会立即更改 。它们不会随着动画实际执行而发生变化(视觉上)。
所以在我的情况下,我将contentOffset设置为我的目标值。 此操作立即调用layoutSubviews。
在我的layoutSubviews实现中,我正在检查是否已经积累了足够的移动。如果是这样 - 我正在重新排列我的ImageViews,并将contentOffset设置为其初始值。一旦我这样做,就没有什么可以动画了,因为没有任何改变!
我不确定这是否是正确的方法,但它的工作正常。 所以我们需要做的是确保在动画块中间不会对layoutSubviews进行任何更改。
所以我创建了一个名为isAnimating的BOOL实例变量,并在动画块中正确设置:
self.isAnimating = YES;
[UIView animateWithDuration:self.transitionDuration
delay:0
options:(UIViewAnimationOptionCurveEaseOut)
animations:^{
self.contentOffset = newOffset;
}
completion:^(BOOL finished) {
self.isAnimating = NO;
[self setNeedsLayout];
}];
现在在layoutSubviews中我们需要考虑isAnimating:
-(void) layoutSubviews
{
[super layoutSubviews];
if (self.isAnimating == NO)
{
[self rearrangeIfNecessary];
}
}
它又恢复了工作!