9

我正在尝试对这个基于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一个设置位置,一个设置边界,它适用于那个视图。

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

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

4

1 回答 1

12

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

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

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

[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 缺少该功能。

于 2013-03-23T01:44:03.960 回答