在 CATransaction 中对自定义 CALayer 属性进行动画处理

发布于 2024-10-01 14:53:01 字数 1207 浏览 9 评论 0原文

到目前为止,我已经能够为 CALayer 子类的自定义属性设置动画,这要归功于 + (BOOL)needsDisplayForKey:(NSString *)key 和 CABasicAnimations

然而事实证明,链接动画可能会变得非常棘手,因为所有代码都发生在单个 animationDidStop:finished: 方法中。

因此,我想切换到 CATransactions,因为它们支持新的块语法,这将允许我使用 + (void)setCompletionBlock:(void (^)(void)) 指定完成块块。

但在我看来,CATransaction 只能对所谓的“可动画属性”进行动画处理,并且它不适用于我的自定义图层属性,即使使用 needsDisplayForKey: 方法也是如此实施的。

那么有没有办法在 CALayer 中创建自定义属性以使用 CATransaction 进行动画处理?

编辑: 我的意图是做一些事情:

[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    NSLog(@"blabla");
}];

myLayer.myProperty = newValue;

[CATransaction commit];

myProperty 值到 newValue 的更新不是动画的。我尝试过实施 actionForLayer:forKey: 在管理 myLayer 的视图中返回一个 CABasicAnimation。但是 actionForLayer:forKey: 永远不会使用 myProperty 键调用。是的,myLayer 不是 view.layer,而是一个子层,是的,我将 myLayer 的委托设置为包含视图。

Until now I've been able to animate the custom properties of my CALayer subclass, thanks to + (BOOL)needsDisplayForKey:(NSString *)key and CABasicAnimations.

However it turns out that chaining animations can become very tricky because all the code takes place in a single animationDidStop:finished: method.

So I wanted to switch to CATransactions since they support the new block syntax, which would allow me to specify a completion block with + (void)setCompletionBlock:(void (^)(void))block.

But it appears to me that CATransaction can only animate the so-called 'animatable properties' and it doesn't work with my custom layer properties, even with the needsDisplayForKey: method implemented.

So is there a way to make custom properties in a CALayer to animate with CATransaction?

EDIT:
My intent is to do something along the lines:

[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    NSLog(@"blabla");
}];

myLayer.myProperty = newValue;

[CATransaction commit];

The update of myProperty value to newValue is not animated. I've tried to implement
actionForLayer:forKey: in the view managing myLayer to return a CABasicAnimation. But actionForLayer:forKey: is never called with the key myProperty. And yes, myLayer is not view.layer but a sublayer, and yes I set the delegate of myLayer to the containing view.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

謌踐踏愛綪 2024-10-08 14:53:01

我相信,根据我对一些源代码的阅读,您仍然可以在 CATransaction 中使用 CABasicAnimation。在 [CATransaction begin][CATransaction commit] 之间添加的任何 CAAnimations 都应该是事务的一部分。

[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    NSLog(@"blabla");
}];

// Create the CABasicAnimation using your existing code
CABasicAnimation *myPropertyAnim = [CABasicAnimation animationWithKeyPath:@"myProperty"];
// TODO: Setup animation range
myPropertyAnim.toValue = newValue;

// The CATransaction does not observe arbitrary properties so this fails:
//myLayer.myProperty = newValue;

// Add the CAAnimation subclass during the CATransaction
[myLayer addAnimation:myPropertyAnim forKey:@"myKey"];

[CATransaction commit];

抱歉,我现在没有一个项目设置可以轻松测试它,但我相信它会起作用。

检查这些网站的代码:

我引用的代码:

[CATransaction begin];
[topLayer addAnimation:topAnimation forKey:@"flip"];
[bottomLayer addAnimation:bottomAnimation forKey:@"flip"];
[CATransaction commit];

I believe, based on my reading of some source code, that you can still use a CABasicAnimation within the CATransaction. Any CAAnimations added between the [CATransaction begin] and [CATransaction commit] should be a part of the transaction.

[CATransaction begin];
[CATransaction setAnimationDuration:0.5];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[CATransaction setCompletionBlock:^{
    NSLog(@"blabla");
}];

// Create the CABasicAnimation using your existing code
CABasicAnimation *myPropertyAnim = [CABasicAnimation animationWithKeyPath:@"myProperty"];
// TODO: Setup animation range
myPropertyAnim.toValue = newValue;

// The CATransaction does not observe arbitrary properties so this fails:
//myLayer.myProperty = newValue;

// Add the CAAnimation subclass during the CATransaction
[myLayer addAnimation:myPropertyAnim forKey:@"myKey"];

[CATransaction commit];

Apologies that I don't have a project setup to easily test this now, but I believe it will work.

Check these site for the code:

Code that I referenced:

[CATransaction begin];
[topLayer addAnimation:topAnimation forKey:@"flip"];
[bottomLayer addAnimation:bottomAnimation forKey:@"flip"];
[CATransaction commit];
风流物 2024-10-08 14:53:01

有一个很棒的类,名为CAAnimationBlocks,并解释了此处,这是 CAAnimation 上的一个类别,允许您像在 UIView 上一样使用完成块。

您只需调用以下命令即可使用它:

CABasicAnimation myAnimation;
[myAnimation setCompletion:^(BOOL finished) { // Do something }];

There's a great class called CAAnimationBlocks, and explained here, that is a category on CAAnimation that allows you to use completion blocks like you would on a UIView.

You use it simply by calling:

CABasicAnimation myAnimation;
[myAnimation setCompletion:^(BOOL finished) { // Do something }];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文