在iOS上,为什么更改CALayer的框架不会导致动画?

nop*_*ole 1 iphone core-animation ios

我有一些iOS示例代码,如果我点击主视图并点击处理程序更改CALayer对象的frame属性,图层对象将设置其位置和大小的动画.

但是,如果我把动画里面ViewControllerviewDidLoad:

UIImage *shipImage = [UIImage imageNamed:@"SpaceShip1.png"];
ship1 = [[CALayer alloc] init];

ship1.contents = (id) [shipImage CGImage];
ship1.frame = CGRectMake(50, 50, 100, 100);

[self.view.layer addSublayer:ship1];

ship1.frame = CGRectMake(0, 0, 300, 200);
Run Code Online (Sandbox Code Playgroud)

那么动画就不会发生.它只会使用(0, 0, 300, 200)没有动画的.为什么这样以及如何使其发挥作用?

Dun*_*n C 6

好几件事.

首先,框架属性不可动画.相反,您应该设置动画边界(更改大小)和位置(移动图层).

引用文档:

注意:frame属性不能直接设置动画.相反,您应该设置边界,anchorPoint和position属性的适当组合的动画,以实现所需的结果.

其次,在更改动画属性之前,必须在添加图层后返回事件循环.

当您返回并且系统访问事件循环时,下次更改动画属性时,它会创建动画事务以设置该更改的动画.

由于您创建了一个图层,设置了它的框架,然后更改了它,所有这些都在返回之前,您的代码只是在它的最后一帧添加了图层.

你应该做的是设置图层,将其安装到它的父图层,然后返回.您可以使用performSelector:withObject:afterDelay:在添加图层后调用动画:

- (void)viewDidLoad
{
  UIImage *shipImage = [UIImage imageNamed:@"SpaceShip1.png"];
  ship1 = [[CALayer alloc] init];

  ship1.contents = (id) [shipImage CGImage];
  ship1.frame = CGRectMake(50, 50, 100, 100);

  [self.view.layer addSublayer:ship1];

  [self performSelector: @selector(changeLayer)
    withObject: nil 
    afterDelay: 0.0];
}


- (void) changeLayer
{
  //Animate changes to bounds and position, not frame.
  ship1.bounds = CGRectMake(0, 0, 300, 200);
  //Note that position is based on the center of the layer by default, so you'll 
  //need to adjust your desired position.
  ship1.position = CGPointMake(0,0);
}
Run Code Online (Sandbox Code Playgroud)

  • 我很确定`frame`也会导致Implicite Animation ...因为我在tap处理程序中尝试了它并且它有效... (2认同)