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

Posted

技术标签:

【中文标题】带有 CATransaction 的 CALayer 动画在视图调整大小之前表现不同【英文标题】:CALayer animation with CATransaction behaving differently when preceded by view resize 【发布时间】:2012-08-02 19:39:27 【问题描述】:

ios 5.1,XCode 4.4)

编辑: 目前(在 iOS 7.0 上),图层似乎始终忽略第一个非动画更改,并始终从原始值开始动画。我无法再重现对视图调整大小的依赖。

我有一个 CALayer,它的位置首先用 [CATransaction setDisableActions:YES] 更改(所以没有动画),然后直接用 [CATransaction 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

【问题讨论】:

您找到解决方案了吗? 【参考方案1】:

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

我通过使用 GCD 的 dispatch_after() 以非常小的延迟做到了这一点。

您还可以通过使用从非动画属性值开始的显式动画来解决此问题。

【讨论】:

【参考方案2】:

您在 setPostion:Animated: 的两次调用中都添加了 animated:YES 因此,该方法两次都在使用

[CATransaction setDisableAction:NO]

而不是

[CATransaction setDisableAction:YES]

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

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

【讨论】:

抱歉,已在示例中更正了该问题。正如文中所描述的,这个问题是关于第一次更改没有动画的情况。

以上是关于带有 CATransaction 的 CALayer 动画在视图调整大小之前表现不同的主要内容,如果未能解决你的问题,请参考以下文章

CATransaction:如何取消?

CATransaction 完成块永远不会触发

CATransaction 动画问题

CATransaction 完成块成功或失败

嵌套 CATransaction 的行为?

CATransaction 和 CAAnimation 有啥区别?