Why addAnimation:forKey not working in viewDidLoaded

I have the following method called by viewDidLoad. This method is to create a CALayer to show a image. This layer has a mask whose path is a UIBezierPath created by my private method. I want the mask to rotate infinitely, and then I add a CABasicAnimation object to the mask.

- (void) createPathLmask
{
    // mask layer
    self.pathLayer                 = [CALayer layer];
    self.pathLayer.bounds          = CGRectMake(0.0, 0.0, 120, 120);

    CGPoint position = self.view.layer.position;
    position.y += 140;
    self.pathLayer.position        = position;
    self.pathLayer.backgroundColor = [UIColor redColor].CGColor;

    UIImage *backimage = [UIImage imageNamed:@"image2"];
    self.pathLayer.contents = (__bridge id)backimage.CGImage;
    self.pathLayer.contentsGravity = kCAGravityResizeAspectFill;

    // mask
    CAShapeLayer *mask = [CAShapeLayer layer];
    mask.bounds          = CGRectMake(0.0, 0.0, 120, 120);
    mask.position        = CGPointMake(60.0f, 60.0f);
    mask.contentsGravity = kCAGravityResizeAspectFill;
    mask.path            = [self createBezierPathInRect:mask.bounds].CGPath;

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // rotate the mask repeatedly
        CABasicAnimation *animation = [CABasicAnimation animation];
        animation.keyPath = @"transform.rotation";
        animation.duration = 4.0f;
        animation.byValue  = @(M_PI * 2);
        animation.repeatCount = HUGE_VALF;
        [mask addAnimation:animation forKey:@"rotation_repeatedly"];
    });

    self.pathLayer.mask = mask;

    [self.view.layer addSublayer:self.pathLayer   ];
}

I find that the rotation animation can only work when I put the addAnimation:forKey into the dispatch_after block with 1 second delay. If those codes are moved out of the block, the mask will not rotate.

So there must be something not ready when animation is added to the layer in viewDidLoaded. I am wondering what is not ready yet? Is there any document or explanation about the suitable chance to add the animation?


So there must be something not ready when animation is added to the layer in viewDidLoaded

Correct. This is way too early for animation. Keep in mind that the view at this point merely exists and that's all; it isn't even part of the interface. You cannot animate a view that isn't part of the view hierarchy. There is nothing, at this point, to animate.

The view first becomes part of the interface between the first call to viewWillAppear and the first call to viewDidAppear . That is what "appear" means (as opposed to what "loaded") means.


There's great documentation on Apple's site here. Putting in simply though:

  • ViewWillAppear - This method is called before the view controller's view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented.
  • 链接地址: http://www.djcxy.com/p/74218.html

    上一篇: 当CALayer暂停并且视图旋转时,iPhone应用程序崩溃

    下一篇: 为什么addAnimation:forKey在viewDidLoaded中不起作用