【问题标题】:Animate frame property using CABasicAnimation使用 CABasicAnimation 动画帧属性
【发布时间】:2013-03-23 01:28:27
【问题描述】:

我正在尝试对这个 UIView 基于块的动画代码进行精确的“翻译”:

[UIView animateWithDuration:0.5
                      delay:0.0
                    options:UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                               someView.frame = CGRect(0, 100, 200, 200);
                             }
                 completion:nil];

使用 CABasicAnimation 代替。

我完全知道 frame 属性实际上是底层的 positionboundsanchorPoint 的组合,因为它在这里描述:http://developer.apple.com/library/mac/#qa/qa1620/_index.html
...我已经做了一个这样的解决方案,使用两个 CABasicAnimations 一个设置 position,一个用于 bounds,它适用于那个看法。

但问题是我的视图中有子视图。 someView 有一个 UIScrollView 类型的子视图,我在其中放置了另一个 UIImageView 类型的子视图。 UIScrollView 子视图的 autoresizingMask 设置为 UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight。如果我使用 UIView 基于块的版本,这一切都可以完美运行,但是当我尝试使用 CABasicAnimations 时,子视图开始出现意外行为(即调整为不正确的宽度)。因此,在使用 CABasicAnimations 时,似乎 autoresizingMask 无法正常工作。我还注意到子视图没有收到对 setFrame: 的调用,尽管在更改层位置和边界后父视图的 frame 属性确实发生了变化。

这就是为什么我想知道使用 CABasicAnimation 复制的正确代码是什么,当使用 UIView 的 animateWithDuration 方法时会发生什么。

【问题讨论】:

    标签: ios objective-c core-animation


    【解决方案1】:

    我完全知道 frame 属性实际上是底层的位置、边界和锚点的组合

    很好,但同样重要的是要注意frame 不是图层的动画属性。如果您想使用 CABasicAnimation 进行动画处理,您必须使用可对图层进行动画处理的属性。 CALayer 文档将每个此类属性都标记为明确的“动画”。使用boundsposition 的想法是正确的。

    因此,这段代码基本上完成了您之前所做的工作:

    [CATransaction setDisableActions:YES];
    // set final bounds and position
    v.layer.bounds = CGRectMake(0,0,200,200);
    v.layer.position = CGPointMake(100,200);
    
    // cause those changes to be animated
    CABasicAnimation* a1 = [CABasicAnimation animationWithKeyPath:@"bounds"];
    a1.duration = 0.5;
    CABasicAnimation* a2 = [CABasicAnimation animationWithKeyPath:@"position"];
    a2.duration = 0.5;
    [v.layer addAnimation:a1 forKey:nil];
    [v.layer addAnimation:a2 forKey:nil];
    

    但是,该代码对v.layer 的任何子层的大小没有影响。 (v 的子视图由v.layer 的子层绘制。)不幸的是,这就是您要解决的问题。我相信通过下降到图层级别并直接显式核心动画,您已经放弃了自动调整大小,这发生在视图级别。因此,您还需要为子图层设置动画。这就是视图动画为您做的事情。

    这是 iOS 的一个不幸功能。 Mac OS X 具有层约束 (CAConstraint),它在层级别执行自动调整大小在视图级别(以及更多)所做的工作。但 iOS 缺少该功能。

    【讨论】:

    • 是的,我创建了两个 CABasicAnimations 一个用于@"position" KeyPath,另一个用于@"bounds"。我已经设置了他们各自的 fromValue 和 toValue。然后我创建了一个 CAAnimationGroup 并将这两个动画添加到其中,然后我将组动画添加到图层。最后,我将 someView.layer.bounds 和 someView.layer.position 设置为新的所需值(用于 toValue),以便更改实际上持续存在于模型层树中。
    • 该动画适用于 someView,它是包含其他子视图的主(父)视图。问题是子视图没有调整大小,它们保持宽度,就好像 autoresizingMask(在它们上设置)有问题一样。使用 UIView animateWithDuration 时一切正常:但是我想使用 CABasicAnimations,因为我需要额外的配置选项...
    • 我和你在一起。我相信因为您是直接为图层设置动画,所以您也必须手动管理子图层的动画。
    • 这就是我所害怕的:(...希望渺茫,但我会再等一会儿,也许有人有什么想法...无论如何谢谢!
    • 我现在正在重新审视如何仍然可以使用 UIView animateWithDuration。我在另一个问题中描述了我的问题,也许你愿意看一下:stackoverflow.com/questions/15582988/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多