微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ios – 如何正确地动画UIScrollView contentOffset

我有UIScrollView子类.它的内容是可重用的 – 大约4或5个视图用于显示数百个元素(当滚动隐藏的对象被重用并在需要查看它们时跳转到另一个位置)

我需要:自动滚动我的滚动视图到任何位置的能力.例如,我的滚动视图显示第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];

但是,现在它在动画开始时只执行一次.

我该如何解决

解决方法

你尝试过同样的方法,但是在scrollViewDidScroll中禁用动画?

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

原文地址:https://www.jb51.cc/iOS/337367.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐