gpt4 book ai didi

ios - 如何在复杂的层次结构中上下同步 CALayer 和 UIView 动画

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:19:29 26 4
gpt4 key购买 nike

参见 How to manage CALayer animations throughout a hierarchy对于仅与如何同步父子层动画有关的后续问题。

这是一个设计问题,涉及在 View 层次结构的不同级别运行依赖动画以响应层次结构中向上的动画。

我有一个容器 Controller ,它有任意数量的子 Controller 。父 Controller 在屏幕上组织此内容,并且在不同的点需要更改其 subview 的大小和位置。

我正在尝试为这些 subview 中的每一个设置动画,以将其大小/形状/位置从它们的原始起点过渡到目的地。带有一些基本动画的基本第一遍开始完成工作。

事情变得更加复杂,因为一些正在调整大小的 View 也应该对 View 的内容执行动画。想象一个内容居中的 subview 。当 child 缩小或扩大时,居中的内容应该与外部动画一起动画以补偿边界变化,使内容保持居中。

为了使事情更加复杂,我还为每个需要与子动画一起设置动画的 subview 设置了一个 mask 层。我还有一些手势不需要使用动画来进行转换 - 所以我需要一种方法来有时为整个 View /图层树设置动画,有时则不需要。

所以所有这些都给了我一个架构,我有类似下面的东西

ContainerViewController.view
-> auxiliary and decorative views
-> WrapperView (multiple)
----> mask layer
-> Child controller view
-> subviews & layers

现在我的问题实际上是可维护性问题。我可以使用显式或隐式动画为这些部分中的每一个制作动画。我需要弄清楚的是确保所有正在完成的动画都是使用相同的持续时间和计时功能完成的最佳方法。目前,我触发了很多这样的属性更改。在某些情况下,属性更改来自 layoutSubviews(从 setNeedsLayout 触发)。

那么,设置这些动画的最佳策略是什么,尤其是显式动画。我能做的最好的就是从 CATransaction 中获取值吗?我担心的是,并不是每个属性都需要在每种情况下都进行动画处理(比如在辅助 View 中)——我已经在打开/关闭 setDisableActions 以强制/拒绝某些属性动画。

是否应该使用 CATransaction 来触发显式 View 动画的设置?如何将为 UIView 动画指定的参数绑定(bind)到将用于底层的参数?下面的代码似乎完成了工作,但看起来真的很难看。

-(void) animateForReason:(enum AnimationReason) animationReason
animations:(void(^)()) animationBlock completion:(void(^)(BOOL)) completionBlock {
const auto animationDuration = 3.0; // make this long to be noticeable!
[UIView animateWithDuration:animationDuration delay:0 options:UIViewAnimationOptionLayoutSubviews
animations:^{
[CATransaction begin];
[CATransaction setAnimationDuration:animationDuration];
animationBlock();
[CATransaction commit];
}completion:completionBlock];
}

我认为 UIViewControllerTransitionCoordinator 已经过时了,因为我需要制作所有这些动画以响应用户操作,而不仅仅是外部事物,例如旋转或帧更改。

最佳答案

有几个选项需要考虑:

  1. 对于 UIView 转换,您可以传递 UIViewAnimationOptionLayoutSubviews 选项。这将在您刚刚更改其框架的 View 上调用 layoutSubviews 之前和之后 subview 之间的更改动画。
  2. 完全不使用 layoutSubviews,您可以覆盖 UIView 上的 setBounds:setFrame: 并且CALayer 子类。这样,如果在动画 block 中调用它们, subview 将与父 View 一起动画。如果它们未在动画 block 内调用,它们将立即更新。

My fear is that not every property needs to be animated in every case (like in the auxiliary views) - I already am flipping setDisableActions on/off to force/deny some property animations.

一般来说,如果你想让它有动画,就把它放在一个动画 block 里,如果你不想,就不要。显然,它可以变得比这更复杂,这就是为什么 Apple 有时会有一个带有 animated 参数的 setter(例如 setSelected:animated:)。

如果您有时开时关的属性,请自行遵循此模式。一种可能的实现方式:

- (void) setNumberOfWidgets:(int)widgetCount animated:(BOOL)animated {
BOOL oldAnimationValue = [UIView areAnimationsEnabled];

if (!animated) {
[UIView setAnimationsEnabled:NO];
}

// a related property which may or may not cause an animation
self.someOtherProperty = someValue;

if (!animated) {
[UIView setAnimationsEnabled:oldAnimationValue];
}
}

My question is really one of maintainability.

是的,听起来您正在考虑某种巨大的对象来为您管理所有的动画可能性。抵制这种诱惑。让每个 View 负责为其自己的 subview 设置动画,并告诉一个 View (不要让它询问)这些更改是否应该设置动画。

I think that UIViewControllerTransitionCoordinator is out because I need to do all of these animations in response to user actions, not just external things, like rotations or frame changes.

是的,没错。不要为此使用 UIViewControllerTransitionCoordinator

关于ios - 如何在复杂的层次结构中上下同步 CALayer 和 UIView 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26879254/

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