gpt4 book ai didi

ios - 如何正确设置 UIScrollView contentOffset 动画

转载 作者:IT王子 更新时间:2023-10-29 08:19:18 30 4
gpt4 key购买 nike

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

我需要什么:能够自动将我的 ScrollView 滚动到任何位置。例如,我的 ScrollView 显示第 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
}];

但是我有一些与滚动事件相关的 Action ,所以现在它们都在动画 block 中,它会导致所有 subview 的帧也有动画(感谢少数可重用元素,它们都不是我想要的动画)

问题是如何为内容偏移制作自定义动画(事实上我需要自定义持续时间、结束时的 Action 和 BeginFromCurrentState 选项)WITHOUT 动画化所有代码, 连接到 scrollViewDidScroll 事件?

更新:感谢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: 只调用一次委托(delegate),它等同于 setContentOffset:animated:NO,再次只调用一次。

setContentOffset:animated:YES 当动画改变 ScrollView 的边界时调用委托(delegate),你想要那个,但你不想要提供的动画,所以我唯一的解决办法可以想出的是逐渐改变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 来制作关键帧动画,但它基本上是一样的,只是语法略有不同。

方法二:您可以尝试使用在动画开始时启动的计时器轮询 ScrollView 的 presentationLayer 是否有任何更改,因为不幸的是,presentationLayer 的属性不是 KVO 可观察的。或者您可以在图层的子类中使用 needsDisplayForKey 以在边界更改时收到通知,但这需要一些工作来设置并且它确实会导致重绘,这可能会影响性能。

方法三:将剖析当动画为 YES 时 scrollView 究竟发生了什么尝试拦截在 scrollview 上设置的动画并更改其参数,但由于 Apple 的更改和最棘手的方法,这将是最 hacky,易碎的,我赢了进入它。

关于ios - 如何正确设置 UIScrollView contentOffset 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21749950/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com