1

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

但是如果我把那个动画放在ViewController's里面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];

ship1.frame = CGRectMake(0, 0, 300, 200);

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

4

3 回答 3

6

几件事。

首先,frame 属性是不可动画的。相反,您应该为边界(以更改大小)和位置(以移动图层)设置动画。

引用文档:

注意:frame 属性不能直接设置动画。相反,您应该对 bounds、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);
}
于 2012-04-29T03:22:02.170 回答
1

您没有指定时间延迟或动画时间。所以对象会在它显示之前被移动,你不会在更早的位置看到它。您还需要返回运行循环以显示任何动画。

于 2012-04-29T01:03:01.320 回答
0

在 iOS 上触发动画有 3 种方式:

1. UIView 动画

您使用UIView.animateWithDuration方法或其他变体直接指定您想要动画。您可以指定持续时间、延迟、完成块等参数。

2. 核心动画 - 隐式动画(期望的方法)

顾名思义,这个动画是在没有明确命令的情况下触发的。但是,为了工作,您需要设置CALayer委托,如下所示:

ship1.delegate = self;

除非您另有说明,否则所有参数都有默认值。要修改这些参数,您需要调用CATransaction

[CATransition setAnimationDuration:0.2];

重要提示:必须在修改图层属性之前放置这些CATransaction调用,因为所有动画都是异步发生的(在不同的运行时线程中),如果你把这些调用放在后面,对你来说已经太晚了。

3.核心动画——显式动画

您创建一个CAAnimation(有不同的CAAnimation子类可供选择)并将其附加到图层:

CABasicAnimation *a = [CABasicAnimation alloc] init....

[ship1 addAnimation:a];

我希望这能澄清对这个主题的一些疑问。

于 2015-02-25T21:23:05.847 回答