Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 链接核心动画_Objective C_Cocoa_Core Animation - Fatal编程技术网

Objective c 链接核心动画

Objective c 链接核心动画,objective-c,cocoa,core-animation,Objective C,Cocoa,Core Animation,在核心动画环境中,哪种最优雅、最模块化的动画链接方式 我的意思是在其他动画刚完成时开始制作动画(例如,更改位置,然后更改不透明度)。。通常的方法是直接更改属性: layer.position = new_point; layer.opacity = 0.0f; 但这同时也会起作用。我想让一个等待另一个 那么如何为不同的对象链接动画呢?我读过关于CATransaction的文章,比如: [CATransaction begin] layer1.property = new_property; [

核心动画环境中,哪种最优雅、最模块化的动画链接方式

我的意思是在其他动画刚完成时开始制作动画(例如,更改
位置
,然后更改
不透明度
)。。通常的方法是直接更改属性:

layer.position = new_point;
layer.opacity = 0.0f;
但这同时也会起作用。我想让一个等待另一个

那么如何为不同的对象链接动画呢?我读过关于
CATransaction
的文章,比如:

[CATransaction begin]
layer1.property = new_property;
[CATransaction begin]
layer2.property2 = new_property2;
[CATransaction commit];
[CATransaction commit];
但它似乎不起作用。

我不相信您可以像示例中那样“嵌套”CA动画

您需要为动画指定一个代理,并将第二个“过渡”放在代理的
animationDidStop:finished:
选择器中


可能想看看苹果的。

您还可以使用动画分组和动画的开始时间字段。试着这样做:

CABasicAnimation *posAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
[posAnimation setFromValue:[NSNumber numberWithFloat:0.0]];
[posAnimation setToValue:[NSNumber numberWithFloat:1.0]];
// Here's the important part
[posAnimation setDuration:10.0];
[posAnimation setBeginTime:0.0];

CABasicAnimation *borderWidthAnimation = [CABasicAnimation animationWithKeyPath:@"borderWidth"];
[borderWidthAnimation setFromValue:[NSNumber numberWithFloat:0.0]];
[borderWidthAnimation setToValue:[NSNumber numberWithFloat:1.0]];
// Here's the important part
[borderWidthAnimation setDuration:10.0];
[borderWidthAnimation setBeginTime:5.0];

CAAnimationGroup *group = [CAAnimationGroup animation];
[group setDuration:10.0];
[group setAnimations:[NSArray arrayWithObjects:posAnimation, borderWidthAnimation, nil]];

[layer addAnimation:group forKey:nil];
CAAnimation *a = ...
CAAnimation *b = ...
CAAnimation *c = ...

a.completionHandler = ^{
    [self.layer addAnimation:b forKey:@"foo"];
    [self.layer addAnimation:c forKey:@"bar"];
};

请注意,整个动画的持续时间为10秒。第一个从第二个0开始,第二个从5秒开始。

正如马特所指出的,可以创建动画组,该组由同一层的不同动画组成,具有不同的开始时间。您还可以为独立的
CAAnimation
对象或
CAAnimation
组设置代理,当每个动画完成时,它将调用
animationDidStop:finished:
代理方法(请注意,组中的动画不会调用其代理的
animationDidStop:finished:
方法)

我想出了一个很酷的技巧,使使用
CAAnimation animation didstop:finished:
方法更强大。我使用方法
setValue:forKey:
向独立动画或动画组添加代码块,并使用@“animationCompletionBlock”键然后,我编写了一个常规的
animationDidStop:finished:
方法,用于检查刚刚完成的动画是否有@“animationCompletionBlock”键,如果找到了,则在那里执行代码块

查看github上的这个项目,了解该技术的一个工作示例:

还可以在中设置一组动画

[CATransaction begin];
//...
[[CATransaction commit];

块,正如您所建议的。当您这样做时,您可以使用
CATransaction
类方法
setCompletionBlock:
在当前事务组中的所有动画完成时调用一个代码块。然后,一个事务的完成块可以触发下一个事务。

我一直喜欢的是s分别设置每个动画的开始和结束时间如下:

我使用了一个DynamicDelegate(它的开发现在正在-Repo中进行,谁知道为什么没有包括我的“工具链”上的所有“技巧”,这个例子不是直接复制/复制的…但是它确实展示了一个非常简单的“链接”动画策略

CATransform3D trans = m34();  // define chain-wide constants.
// Name your "stack". My "nextObject" returns arr[i]->done == nil. 
NSArray *layerStack = layer.sublayers;
//define a block, that "takes" a layer as it's argument.
void(^__block ChainBlock)(CALayer*) = ^(CALayer *m) { 
// animations, transforms, etc for each inividual "step".
    [m animate:@"transform" 
          // These are just NSValue-wrapped CAT3D's
          from:AZV3d(CATransform3DRotate(trans,  0,1,0,0)) 
            to:AZV3d(CATransform3DRotate(trans,1.5,1,0,0)) 
          time:2    // total time == each step * layerStack.count
         eased:kCAMediaTimingFunctionEaseOut
    completion:^{   // In completion, look for "next" layer.
                    CAL*  m2 = [layers nextObject]; 
// If there is "another" layer, call this block, again... with it.
                      if (m2)  chainAnis(m2);
// Otherise,you're done.  Cleanup, toggle values, whatevs.
                     else self.finishedProperty = YES;
    }];
};
// Give the block we just defined your "first" layer.
ChainBlock(layerStack[0]);  // It will recursively feed itself.

这显然取决于一些“外部魔法”,但概念很简单,并且消除了(通过依赖关系)“处理”的需要任何类型的总授权。特别是
动画:从:到:时间:放松:完成
,等等。类别来自伟大。

我使用
setCompletionBlock
方法定义一个闭包,在第一个动画完成时触发下一个动画:

[CATransaction begin]
layer1.property = new_property;
CATransaction.setCompletionBlock {
    [CATransaction begin]
    layer2.property2 = new_property2;
    [CATransaction commit];
}
[CATransaction commit];

请注意,这很好,但仅适用于应用于单个层的动画。此外,如果要在第一个动画完成后立即调用方法,则不能。仅当整个组完成时才会调用animationDidStop。关键点路径
“位置”
是一个
CGPoint
,需要使用
NSValue
进行编码(而不是
NSNumber
)。