使用基于块的UIView动画与CAMediaTimingFunction

3

iOS视图编程指南告诉我们,基于块的动画是未来的趋势,而不是现在几乎被弃用的begin/commit样式动画:

注意:如果您正在为iOS 4或更高版本编写应用程序,则应改用基于块的方法来动画显示内容。有关如何使用这些方法的信息,请参见“使用基于块的方法启动动画”。

但是现在我遇到了需要使用自定义计时函数CAMediaTimingFunction的情况,所以我使用了CATransactionCABasicAnimation。这些类使用与已弃用的UIView动画样式相同的语义语言,例如[CATransaction begin][CATransaction commit]方法。在一切都是基于块的应用程序中,这感觉很奇怪。

是否有一种方法可以将CAMediaTimingFunction等概念与基于块的动画结合起来?

更新1:

我想要“块化”的示例代码如下所示:*

[CATransaction begin];
{    
    [CATransaction setValue:[NSNumber numberWithFloat:3.0f] forKey:kCATransactionAnimationDuration];

    CGPoint low = CGPointMake(0.150, 0.000);
    CGPoint high = CGPointMake(0.500, 0.000);

    [CATransaction begin];
    {
        CAMediaTimingFunction* perfectIn = [CAMediaTimingFunction functionWithControlPoints:low.x :low.y :1.0 - high.x :1.0 - high.y];
        [CATransaction setAnimationTimingFunction: perfectIn];
        CABasicAnimation *fadeIn = [CABasicAnimation animationWithKeyPath:@"opacity"];
        fadeIn.fromValue = [NSNumber numberWithFloat:0];
        fadeIn.toValue = [NSNumber numberWithFloat:1.0];
        [viewB.layer addAnimation:fadeIn forKey:@"animateOpacity"];
    }
    [CATransaction commit];
}
[CATransaction commit];

更新2

我为我另一个问题制作了一个示例项目,其中包含上述代码。 它在github上


UIView 上创建一个类别,其中包含一个将 CAAnimation 相关内容封装在一个漂亮的块中的方法,怎么样? - Paul.s
如果这个问题没有答案,那么感觉就像是在重新发明轮子,但这将是我不得已而为之的选择。 - epologee
因为 CABasicAnimations 的缘故,这也会变得相当困难。 @Paul.s 您愿意尝试编写一个吗? - epologee
如果您能给我一个样例(未经过阻塞的)让我开始尝试一下... - Paul.s
2个回答

5
但是现在我需要使用自定义时间函数 CAMediaTimingFunction,所以我已经转而使用 CATransactions 和 CABasicAnimations。这些类使用与已弃用的 UIView 动画样式相同的语义语言,例如 [CATransaction begin] 和 [CATransaction commit] 方法。在应用程序的中间使用它只是感觉很奇怪,因为其他所有东西都是基于块的。
我认为您误读了文档。
基于块的动画是执行 UIView 动画的方法。 完全正确。
此声明不对应 CoreAnimation。 您仍然必须为 CoreAnimation 使用 begin/commit。 不要假设 CA begin 和 commit 是不好的,只是因为更高级别的构造(UIView)已弃用了 begin/commit。
是否有一种方法将 CAMediaTimingFunctions 这样的概念与基于块的动画结合起来?
如果您需要 Core Anmiation 的高级功能(例如自定义定时),则应按照其预期使用 CoreAnimation(包括 begin/commit 等)。
如果您要对 CALayer 进行动画处理,请使用 Core Animation。
如果您正在进行高级别的基于 UIView 的动画处理,请使用 UIView 基于块的动画。

这实际上很有道理。 - epologee
3
真正的问题在于无法为基于UIView的动画指定时间函数。据我所知,你只能从一系列不愉快的选项中选择: - nomothetis
@amatth,我该如何在特定时间添加水印。我的视频长度为60秒,我想在第10秒到第50秒添加水印。请帮帮我。 - sohil

1

现在我要承认这看起来相当无意义,但这是我能想到的最快的方法,可以为您提供一个块接口,并且它可以防止您意外地遗漏开始/提交

.h

+ (void)transactionWithDuration:(NSTimeInterval)duration
                     animations:(void (^)(void))animations;

.m

+ (void)transactionWithDuration:(NSTimeInterval)duration
                     animations:(void (^)(void))animations;
{
    [CATransaction begin];
    [CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration];
    animations();
    [CATransaction commit];
}

在您的代码中使用(假设您已将其作为UIView的类别)

[UIView transactionWithDuration:3 animations:^{

    CGPoint low  = CGPointMake(0.150, 0.000);
    CGPoint high = CGPointMake(0.500, 0.000);

    CAMediaTimingFunction* perfectIn = 
        [CAMediaTimingFunction functionWithControlPoints:low.x 
                                                        :low.y 
                                                        :1.0 - high.x 
                                                        :1.0 - high.y];
    [CATransaction setAnimationTimingFunction: perfectIn];
    CABasicAnimation *fadeIn = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fadeIn.fromValue = [NSNumber numberWithFloat:0];
    fadeIn.toValue = [NSNumber numberWithFloat:1.0];
    [viewB.layer addAnimation:fadeIn forKey:@"animateOpacity"];

}];

谢谢你提供这些类别,这已经是我能添加的最优雅的部分了:D。我无法摆脱这样一种感觉,即在基于块的世界中必须有更加优雅的方法来利用那些自定义的CA特性。即使对于Objective-C来说,这似乎也很繁琐,你不觉得吗? - epologee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接