带有CATransaction的CALayer动画在视图调整之前表现不同



(iOS 5.1,XCode 4.4)

编辑:当前(在iOS 7.0上),该层似乎始终忽略第一个未设置动画的更改,并始终从原始值设置动画。我无法再复制视图大小调整的依赖关系。

我有一个CALayer,它的位置首先用[CATransaction setDisableActions:YES]更改(因此未设置动画),然后直接用[CATtransaction setDisableActions:NO]更改(设置动画)。通常,这将导致从第一次更改中设置的位置到第二次更改中设定的位置的动画。然而,我发现我的代码从初始位置变成了第二次更改后的位置。

经过大量的测试和调试,我发现它依赖于包含在更改之前调整大小的层的UIView。要复制的代码(iphone单视图模板,添加QuartzCore.framework):

#import <QuartzCore/QuartzCore.h>
#import "TAViewController.h"
@interface TAViewController ()
@property (nonatomic, strong) UIView *viewA;
@property (nonatomic, strong) CALayer *layerA;
@end
@implementation TAViewController
- (IBAction)buttonPressed
{
    self.viewA.frame = CGRectMake(0, 30, 320, 250);
    [self setPosition:CGPointMake(0, 100) animated:NO];
    [self setPosition:CGPointMake(0, 150) animated:YES];
}
- (void)setPosition:(CGPoint)position animated:(BOOL)animated
{
    [CATransaction begin];
    if(animated) {
        [CATransaction setDisableActions:NO];
        [CATransaction setAnimationDuration:5];
    } else {
        [CATransaction setDisableActions:YES];
    }
    self.layerA.position = position;
    [CATransaction commit];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.viewA = [[UIView alloc] init];
    self.viewA.backgroundColor = [UIColor darkGrayColor];
    self.viewA.frame = CGRectMake(0, 30, 320, 300);
    [self.view addSubview:self.viewA];
    self.layerA = [CALayer layer];
    self.layerA.backgroundColor = [UIColor redColor].CGColor;
    self.layerA.anchorPoint = CGPointZero;
    self.layerA.frame = CGRectMake(0, 0, 320, 100);
    [self.viewA.layer addSublayer:self.layerA];
}
@end

我遇到了类似的问题,并通过延迟动画属性更改来解决它,这可能会将它们推入下一个运行循环,从而确保之前的属性更改在隐式动画开始之前生效。

我通过使用GCD的dispatch_after()来实现这一点,延迟很小。

您也可以通过使用从未设置动画的特性值开始的显式动画来解决此问题。

您在对setPostion:animated:的两次调用中都设置了animated:YES。因此,两次该方法都使用

[CATransaction setDisableAction:NO]

而不是

[CATransaction setDisableAction:YES]

我认为你按下按钮的方法应该改为

[self setPosition:CGPointMake(0, 100) animated:NO];
[self setPosition:CGPointMake(0, 150) animated:YES];

最新更新