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