Iphone CABasicAnimation不设置我的属性的动画

Iphone CABasicAnimation不设置我的属性的动画,iphone,animation,core-animation,properties,Iphone,Animation,Core Animation,Properties,我一直在试图理解我的动画有什么问题,但我仍然没有弄明白。我认为这应该是非常直截了当的,但即使在阅读了大量的示例和文档之后,我也可能遗漏了一些东西 我的问题源于这样一个事实:在iPhone上,无法自动调整层的大小(使用视图)。文档中另有说明,但SDK中没有该层的autoresizeMask。所以我决定做一点变通,自己制作图层动画 我有一段简单的代码,可以做一个简单的调整动画。这些值很好,我甚至设置了代理以跟踪动画的开始/结束 // I've got a property named layerIm

我一直在试图理解我的动画有什么问题,但我仍然没有弄明白。我认为这应该是非常直截了当的,但即使在阅读了大量的示例和文档之后,我也可能遗漏了一些东西

我的问题源于这样一个事实:在iPhone上,无法自动调整层的大小(使用视图)。文档中另有说明,但SDK中没有该层的autoresizeMask。所以我决定做一点变通,自己制作图层动画

我有一段简单的代码,可以做一个简单的调整动画。这些值很好,我甚至设置了代理以跟踪动画的开始/结束

// I've got a property named layerImage (which is a CALayer)
- (void)animateTestWithFrame:(CGRect)value {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"layerImage.frame"];
    animation.duration = 1;
    animation.fromValue = [NSValue valueWithCGRect:self.frame];
    animation.toValue = [NSValue valueWithCGRect:value];
    animation.removedOnCompletion = YES;
    animation.delegate = self;

    [self.layer addAnimation:animation forKey:@"layerImage.frame"];
}
有什么想法吗?(此包含代码的视图是窗口子视图的子视图,如果这可能会产生影响的话)

---编辑---


似乎帧无法通过CABasicAnimation和命名属性“frame”设置动画。当使用边界时,我得到了一些奇怪的结果,但至少我得到了一些东西。将继续对此进行调查。

密钥路径应仅为属性的密钥路径,而不是对象的名称

用这个

[CABasicAnimation animationWithKeyPath:@"frame"]
而不是这个

[CABasicAnimation animationWithKeyPath:@"layerImage.frame"]

顺便说一句,当你给一个层添加动画时,关键点并不意味着要设置动画的关键点属性。只有您希望此动画具有的关键点(名称)(这是指代码的最后一行)

因此,解决方案是为层的@“边界”和@“位置”设置动画,因为在iPhone上无法为帧设置动画。我花了一些时间才明白,位置是层的中心,边界的大小是从中心延伸的,但这是容易的部分

所以,我在简历中所做的是:

  • 在setFrame中,使用bounds和position属性创建2个动画
  • 使用“animation.removedOnCompletion=NO;animation.fillMode=kCAFillModeForwards;”确保在动画结束时不会重置这些值
  • 将委托注册到self以实现“animationDidStop:finished:”。似乎您仍然需要设置值:“layerImage.bounds=[animation.toValue CGRectValue];layerImage.position=[animation.toValue CGPointValue];”
  • 我无法直接使用UIView动画系统,因为它在层上没有实现我想要的功能

    感谢tadej5553指出我在“addAnimation”中遇到的层问题。下面是代码,供那些想看看它是什么样子的人使用

    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
        CABasicAnimation *animation = (CABasicAnimation*)anim;
    
        if ([animation.keyPath isEqualToString:@"bounds"]) {
            layerImage.bounds = [animation.toValue CGRectValue];
        } else if ([animation.keyPath isEqualToString:@"position"]) {
            layerImage.position = [animation.toValue CGPointValue];
        }
    }
    
    - (void)setFrame:(CGRect)value {
        CGRect bounds = CGRectMake(0, 0, value.size.width, value.size.height);
    
        if ([UIView isAnimationStarted]) {
            // animate the bounds
            CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
            animation.duration = [UIView animationDuration];
            animation.fromValue = [NSValue valueWithCGRect:layerImage.bounds];
            animation.toValue = [NSValue valueWithCGRect:bounds];
            animation.removedOnCompletion = NO;
            animation.fillMode = kCAFillModeForwards;
            animation.timingFunction = [UIView animationFunction];
            animation.delegate = self;
            [layerImage addAnimation:animation forKey:@"BoundsAnimation"];
    
            // animate the position so it stays at 0, 0 of the frame.
            animation = [CABasicAnimation animationWithKeyPath:@"position"];
            animation.duration = [UIView animationDuration];
            animation.fromValue = [NSValue valueWithCGPoint:layerImage.position];
            animation.toValue = [NSValue valueWithCGPoint:CGPointMake(bounds.size.width / 2, bounds.size.height / 2)];
            animation.removedOnCompletion = NO;
            animation.fillMode = kCAFillModeForwards;
            animation.timingFunction = [UIView animationFunction];
            animation.delegate = self;
            [layerImage addAnimation:animation forKey:@"PositionAnimation"];
        } else {
            layerImage.frame = bounds;
        }
    
        [super setFrame:value];
    }
    

    所以,你在这里解决了问题,这很好,但你对自己问题的回答有些不准确。让我纠正几件事:

    帧属性可以设置动画,但不能使用显式动画。如果对视图的根层以外的层执行以下操作,则帧的动画效果会很好:

    [CATransaction begin];
    [CATransaction setAnimationDuration:2.0f];
    [animationLayer setFrame:CGRectMake(100.0f, 100.0f, 100.0f, 100.0f)];
    [CATransaction commit];
    
    请记住,默认情况下,在图层上设置特性将设置该特性更改的动画。事实上,如果不希望属性更改设置动画,则必须禁用属性更改上的动画。(当然,只有在为视图的根层以外的层设置动画时才是如此。)如果需要使用显式动画,则可以正确设置位置和边界的动画

    可以使用隐式动画为UIView上的帧设置动画:

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:3.0f];
    [[self view] setFrame:CGRectMake(45.0f, 45.0f, 100.0f, 100.0f)];
    [UIView commitAnimations];
    
    这将从视图的当前帧(边界和位置)设置动画,使x=45.0,y=45.0,w=100.0,h=100.0

    您可能还误解了动画和层之间的区别。将动画添加到层,但将动画添加到层不会自动设置正在设置动画的特性

    Calayer是模型对象。它们包含有关最终渲染到屏幕的层的信息。如果希望层的属性实际具有该值,则必须设置该层的属性。如果只是设置属性的动画,它将只是一个视觉表示,而不是实际的-这就是为什么该值会捕捉回层的原始值,因为您从未实际更改过它

    这就引出了下一点。你说:

    使用“animation.removedOnCompletion”= 否;animation.fillMode= kCAFillModeForwards;”以确保 这些值不会在最后重置 动画艺术

    这并不完全正确。这两个值只会使动画在视觉上保持在其最终位置,但层的实际值没有改变。它们仍然与启动动画时的值完全相同。一般来说(除了少数例外),您不想使用这两个参数,因为它们仅是可视的。您需要的是为正在设置动画的特性实际设置层值

    例如,假设要使用显式动画设置层位置的动画。以下是您需要的代码:

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    [animation setFromValue:[NSValue valueWithCGPoint:CGPointMake(70.0f, 70.0f)]];
    [animation setToValue:[NSValue valueWithCGPoint:CGPointMake(150.0f, 150.0f)]];
    [animation setDuration:2.0f];
    
    // Actually set the position on the *layer* that you want it to be
    // when the animation finishes.
    [animationLayer setPosition:CGPointMake(150.0f, 150.0f)];
    
    // Add the animation for the position key to ensure that you
    // override the animation for position changes with your animation.
    [animationLayer addAnimation:animation forKey:@"position"];
    

    你也可以考虑动画分组。使用动画组,可以将多个动画组合在一起,然后控制它们之间的关系。在您的情况下,边界动画和位置动画的持续时间是相同的,因此您尝试在没有组的情况下执行的操作会很好,但是如果您希望偏移动画的开始,例如,您不希望位置动画在帧动画中的一秒或两秒之前开始,可以通过设置位置动画的起始时间值来错开它们

    最后,我想知道为什么不能使用UIView上的隐式动画。我在编写的绝大多数核心动画代码中都使用了这些代码,但我不明白为什么这样做不适合您的情况


    致以最诚挚的问候。

    对于帧来说是可以的,但是CABasicAnimation如何知道要为该属性设置动画的层?这是否意味着我必须做[layerImage addAnimation:animation…]。(T