ios – 如何正确地动画UIScrollView contentOffset

前端之家收集整理的这篇文章主要介绍了ios – 如何正确地动画UIScrollView contentOffset前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有UIScrollView子类.它的内容是可重用的 – 大约4或5个视图用于显示数百个元素(当滚动隐藏的对象被重用并在需要查看它们时跳转到另一个位置) @H_403_2@我需要:自动滚动我的滚动视图到任何位置的能力.例如,我的滚动视图显示第4,第5和第6个元素,当我点击一些按钮,它需要滚动到第30个元素.换句话说,我需要UIScrollView的标准行为.

@H_403_2@这工作正常:

[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中包装代码

[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上设置的动画并更改其参数,但由于这将是最恶作剧的,因为苹果的变化和棘手的方法,我赢了不要进去

猜你在找的iOS相关文章