我需要:自动滚动我的滚动视图到任何位置的能力.例如,我的滚动视图显示第4,第5和第6个元素,当我点击一些按钮,它需要滚动到第30个元素.换句话说,我需要UIScrollView的标准行为.
这工作正常:
[self setContentOffset:CGPointMake(index*elementWidth,0) animated:YES];
但我需要一些定制.例如,更改动画持续时间,添加一些代码以在动画结束时执行.
明显的决定:
[UIView animateWithDuration:3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ [self setContentOffset:CGPointMake(index*elementWidth,0)]; } completion:^(BOOL finished) { //some code }];
但我有一些动作连接到滚动事件,所以现在所有的都在动画块,它导致所有子视图的帧动画(由于几个可重用的元素,所有这些都不是我想要的动画)
问题是:如何制作自定义动画(实际上我需要自定义持续时间,结束操作和BeginFromCurrentState选项)用于内容偏移量,而不是动画化所有代码,连接到scrollViewDidScroll事件?
UPD:
感谢Andrew’s answer(第一部分)我解决了scrollViewDidScroll中的动画问题:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ [UIView performWithoutAnimation:^{ [self refreshTiles]; }]; }
但是scrollViewDidScroll必须(为了我的目的)执行动画的每一帧,就像在这样的情况下
[self setContentOffset:CGPointMake(index*elementWidth,0) animated:YES];
但是,现在它在动画开始时只执行一次.
我该如何解决?
解决方法
在iOS 7中,您可以尝试在scrollViewDidScroll中包装代码
[UIView performWithoutAnimation:^{ //Your code here }];
在以前的iOS版本上,您可以尝试:
[CATransaction begin]; [CATransaction setDisableActions:YES]; //Your code here [CATransaction commit];
更新:
不幸的是,这是你整个事情艰难的一部分. setContentOffset:只调用一次代理,它等同于setContentOffset:animated:NO,它再次调用它一次.
setContentOffset:animated:YES调用代理,因为动画改变了scrollview的界限,而且你想要的,但是你不想提供动画,所以我可以想出的唯一办法就是逐渐改变contentOffset的滚动视图,所以动画系统不会跳到最终的值,就像这样的情况.
为此,您可以查看关键帧动画,如iOS 7所示:
[UIView animateKeyframesWithDuration:duration delay:delay options:options animations:^{ [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{ [self setContentOffset:CGPointMake(floorf(index/2) * elementWidth,0)]; }]; [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{ [self setContentOffset:CGPointMake(index*elementWidth,0)]; }]; } completion:^(BOOL finished) { //Completion Block }];
这将给你两个更新,当然你可以使用一些数学和循环来加上更多的这些与适当的时间.
在以前的iOS版本中,您必须将关键帧动画放在CoreAnimation上,但基本相同的是使用一些不同的语法.
方法2:
您可以尝试使用您在动画开始时启动的计时器来轮询scrollview的presentationLayer,因为不幸的是presentationLayer的属性不是KVO可观察的.或者,您可以在层的子类中使用needsDisplayForKey,以便在边界更改时收到通知,但这需要一些工作来设置,并且会导致重新绘制,这可能会影响性能.
方法3:将要剖析scrollView中发生的动画是否尝试并截取在scrollview上设置的动画并更改其参数,但由于这将是最恶作剧的,因为苹果的变化和棘手的方法,我赢了不要进去