Reputation: 7665
(iOS 5.1, XCode 4.4)
EDIT: Currently (on iOS 7.0), the layer seems to consistently ignore the first non-animated change, and always animate from the original value. I can no longer reproduce the dependency on view resize.
I have a CALayer whose position is first changed with [CATransaction setDisableActions:YES] (so not animated) and directly afterwards changed with [CATransaction setDisableActions:NO] (animated). Normally, this would result in an animation from the position set in the first change to the position set in the second change. However, I found that my code animated from the initial position to the position from the second change instead.
After a lot of testing and debugging, I found that it depended on the UIView containing the layer being resized before the changes. Code to reproduce (iphone single view template, add 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
Upvotes: 4
Views: 2537
Reputation: 5999
I was having a similar issue and solved it by delaying the animated property changes, which probably had the effect of pushing them into the next run loop and thereby ensuring that the previous property changes had taken effect before the implicit animation began.
I did this by using GCD's dispatch_after() with a very small delay.
You might also be able to address this issue by using an explicit animation that begins from the non-animated property value.
Upvotes: 2
Reputation: 1352
you put animated:YES in both of your calls to setPostion:Animated: Therefore, both times that method is using
[CATransaction setDisableAction:NO]
instead of
[CATransaction setDisableAction:YES]
I think your button pressed method should be changed to
[self setPosition:CGPointMake(0, 100) animated:NO];
[self setPosition:CGPointMake(0, 150) animated:YES];
Upvotes: 0