为了说明这个问题,我gisted在Github上一个非常小的Xcode项目(两班,11KB下载)。 看看这里的要点或使用git克隆git@gist.github.com:93982af3b65d2151672e.git。
请考虑以下情形。 我的一个自定义视图,称为“容器视图” ,包含两个小广场。 在所示这个截图:
蓝色方块是一个22×22磅UIView
实例和红场PT一22×22 CALayer
实例。 对于这个问题的目的,我想这两个广场,以“大棒”,以外观图的右下角,而我是动画外视图的框架。
我改变容器视图的一个内帧UIView
的类方法animateWithDuration:delay:options:animations:completion:
与类型的非默认参数宽松UIViewAnimationCurveEaseOut
。
[UIView animateWithDuration:1.0 delay:0
options:UIViewAnimationCurveEaseOut
animations:^{ _containerView.frame = randomFrame; }
completion:nil];
注意:两个蓝色的UIView的,红色的CALayer的框架中重写设置setFrame:
容器视图的方法,但结果将是相同的,如果我已成立了蓝色的UIView的autoresizingMask
属性的UIView灵活的左侧和顶部边缘。
在生成的动画中,蓝方“棍棒”墙角现在的样子我预期的,但红方完全忽视动画的定时和宽松。 我想这是因为核心动画,以前已经帮我在很多场合功能的隐式动画功能。
下面是动画序列几张截图是说明了两个正方形的异步性:
对这个问题: 有没有办法使红色的CALayer和UIView的蓝色都具有相同的动画持续时间和缓和曲线移动,相互粘在一起,好像他们是一个以同步两个框架的变化?
PS当然,两个正方形粘在一起所需的视觉结果,可以在任何数量的方式具有两层成为既可以实现,例如CALayer
S或UIView
S,但真正的问题是在项目中有一个非常合法的原因对于一个要一个CALayer的,另一个是一个UIView。
我假设你有正确的,而且,视图和层对齐动画后结束位置。 这已无关的动画,只是形状。
当您更改的属性CALayer
这不是一个视图层 (如你的情况),它会隐式动画到新的价值。 要自定义此动画,你可以使用一个明确的动画,就像一个基本的动画。 在一个基本的动画改变帧会是这个样子。
CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
[myAnimation setToValue:[NSValue valueWithCGRect:myNewFrame]];
[myAnimation setFromValue:[NSValue valueWithCGRect:[myLayer frame]]];
[myAnimation setDuration:1.0];
[myAnimation setTimingFunction:[CAMediaTimingFuntion functionWithName: kCAMediaTimingFunctionEaseOut]];
[myLayer setFrame:myNewFrame];
[myLayer addAnimation:myAnimation forKey:@"someKeyForMyAnimation"];
如果定时功能和两个动画的持续时间相同,则他们应该保持一致。
还要注意的是明确的动画不改变价值和帽子,你必须既能补充动画,并设置新的值(比如在样品上面)
是的,有许多方法来达到同样的效果。 一个实例是具有视图和层是相同的子视图的子视图(其又是外框的子视图)。
编辑
你不能轻易使用显式动画组UIView的动画。 你也不能使用动画组(因为你是它们适用于不同的层),但是哟可以使用CATransaction:
[CATransaction begin];
[CATransaction setAnimationDuration:1.0];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFuntion functionWithName: kCAMediaTimingFunctionEaseOut]];
// Layer animation
CABasicAnimation *myAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
[myAnimation setToValue:[NSValue valueWithCGRect:myNewFrame]];
[myAnimation setFromValue:[NSValue valueWithCGRect:[myLayer frame]]];
[myLayer setFrame:myNewFrame];
[myLayer addAnimation:myAnimation forKey:@"someKeyForMyAnimation"];
// Outer animation
CABasicAnimation *outerAnimation = [CABasicAnimation animationWithKeyPath:@"frame"];
[outerAnimation setToValue:[NSValue valueWithCGRect:myNewOuterFrame]];
[outerAnimation setFromValue:[NSValue valueWithCGRect:[outerView frame]]];
[[outerView layer] setFrame:myNewOuterFrame];
[[outerView layer] addAnimation:outerAnimation forKey:@"someKeyForMyOuterAnimation"];
[CATransaction commit];
如果你想大卫Rönnqvist在雨燕3.0片断,在这里你有它:
CATransaction.begin()
CATransaction.setAnimationDuration(1.0)
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut))
// Layer animation
let myAnimation = CABasicAnimation(keyPath: "frame");
myAnimation.toValue = NSValue(cgRect: myNewFrame)
myAnimation.fromValue = NSValue(cgRect: myLayer.frame)
myLayer.frame = myNewFrame
myLayer.add(myAnimation, forKey: "someKeyForMyAnimation")
// Outer animation
let outerAnimation = CABasicAnimation(keyPath: "frame")
outerAnimation.toValue = NSValue(cgRect: myNewOuterFrame)
outerAnimation.fromValue = NSValue(cgRect: outerView.frame)
outerView.layer.frame = myNewOuterFrame
outerView.layer.add(outerAnimation, forKey: "someKeyForMyOuterAnimation")
CATransaction.commit()