iOS - CATransition问题:在开始时显示结束图像

时间:2014-01-16 14:19:20

标签: ios core-animation catransition

在我的UIViewController我使用image1创建CALayer

CALayer *imageLayer = [CALayer layer];
[imageLayer setBounds:CGRectMake(0.0, 0.0, 241.0, 430.0)];
[imageLayer setPosition:CGPointMake(160.0, 60.0)];
[imageLayer setAnchorPoint:CGPointMake(0.5, 0.0)];
[imageLayer setContents:(id)[UIImage imageNamed:@"image1.png".CGImage];
[imageLayer setContentsGravity:kCAGravityResizeAspect];
[self.view.layer addSublayer:imageLayer];

稍后在UIViewController我希望通过使用CATransition推送图片来更改图片。

CATransition *t = [CATransition animation];
t.beginTime = [self.view.layer convertTime:CACurrentMediaTime() + 6.5 fromLayer:nil];
t.type = kCATransitionPush;
t.subtype = kCATransitionFromRight;
[imageLayer setContents:(id)[UIImage imageNamed:@"image2.png"].CGImage];    
[imageLayer addAnimation:t forKey:nil];

当我运行代码时,我从头开始获得image2,但是在6.5秒之后通过推送自身进行转换。 image1在哪里?怎么了?

正确答案: 谢谢Jacky Boy和Tiago Almeida。 我更正了删除行的代码

t.beginTime = [self.view.layer convertTime:CACurrentMediaTime() + 6.5 fromLayer:nil];

并添加'dispatch_after'。

现在可行:

CATransition *t = [CATransition animation];
t.type = kCATransitionPush;
t.subtype = kCATransitionFromRight;
[imageLayer setContents:(id)[UIImage imageNamed:@"image2.png"].CGImage];    
[imageLayer addAnimation:t forKey:nil];
[CATransaction begin];
NSTimeInterval delayInSeconds = 6.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [imageLayer setContents:(id)[UIImage imageNamed:@"image2.png"].CGImage];
    [imageLayer addAnimation:t forKey:nil];
});
[CATransaction commit];

再次感谢,伙计们!

3 个答案:

答案 0 :(得分:3)

删除以下行:

t.beginTime = [self.view.layer convertTime:CACurrentMediaTime() + 1.5 fromLayer:nil];

这是延迟动画的内容,因此图层正在设置新内容,并且仅在图层动画之后。如果要指定动画的持续时间:

[CATransaction begin];
[CATransaction setAnimationDuration:1.0];

CATransition *t = [CATransition animation];
t.type = kCATransitionPush;
t.subtype = kCATransitionFromRight;
[_layer setContents:(id)[UIImage imageNamed:@"image2.jpg"].CGImage];
[_layer addAnimation:t forKey:nil];


[CATransaction commit];

或更小的版本:

CATransition *t = [CATransition animation];
t.type = kCATransitionPush;
[t setDuration:2.5];
t.subtype = kCATransitionFromRight;
[_layer setContents:(id)[UIImage imageNamed:@"image2.jpg"].CGImage];
[_layer addAnimation:t forKey:nil];

我更喜欢这个:

CATransition *transition = [CATransition animation];
transition.type = kCATransitionPush;
transition.duration = .25f;
transition.subtype = kCATransitionFromRight;

_layer.actions = @{@"contents": transition};

当您想要更改内容时:

[_layer setContents:(id)[UIImage imageNamed:@"image2.jpg"].CGImage];

答案 1 :(得分:1)

您正在创建imageLayer但正在配置currentCharacterImageLayer

答案 2 :(得分:0)

这里的正确解决方案实际上是在过渡上使用fillMode属性。即(对不起,斯威夫特)

transition.fillMode = .backwards

docs

如果延迟动画的开始,则可能还需要将fillMode属性设置为kCAFillModeBackwards。即使图层树中的图层对象包含其他值,此填充模式也会使图层显示动画的起始值。如果没有这种填充模式,您将看到动画开始执行之前跳到最终值的情况。其他填充模式也可用。

dispatch_after在某些情况下可以使用,但是如果您需要制作动画,例如使用CATransaction

感谢您发布问题,它使我走上了寻找答案的正确轨道