【问题标题】:Using CAMediaTimingFunction with block-based UIView animations将 CAMediaTimingFunction 与基于块的 UIView 动画一起使用
【发布时间】:2011-11-13 17:29:01
【问题描述】:

View Programming Guide for iOS 告诉我们,基于块的动画是前进的方向,而不是现在几乎已弃用的 begin/commit 样式动画:

注意:如果您正在为 iOS 4 或更高版本编写应用程序,则应使用基于块的方法来为您的内容设置动画。有关如何使用这些方法的信息,请参阅“Starting Animations Using the Block-Based Methods.”

但现在我需要使用自定义计时函数CAMediaTimingFunction,所以我求助于使用CATransactions 和CABasicAnimations。这些类使用与已弃用的 UIView 动画样式相同的语义语言,使用 [CATransaction begin][CATransaction commit] 等方法。在其他一切都是基于块的应用程序中间感觉很奇怪。

有没有办法将CAMediaTimingFunctions 等概念与基于块的动画结合起来?

更新 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

我为我的另一个问题制作了一个示例项目,其中包含上面的代码。 It's on github.

【问题讨论】:

  • 如何在UIView 上创建一个类别,方法是将CAAnimation 内容包装在一个漂亮的块中?
  • 感觉就像在重新发明轮子,但如果这个问题没有得到答案,我就会求助。
  • 由于 CABasicAnimations,它也将变得相当困难。想试试写一个吗,@Paul.s?
  • 如果你愿意给我一个样品(预块)开始我会去...

标签: objective-c cocoa-touch cocoa core-animation objective-c-blocks


【解决方案1】:

但现在我需要使用自定义计时函数 CAMediaTimingFunction,所以我求助于使用 CATransactions 和 CABasicAnimations。这些类使用与已弃用的 UIView 动画样式相同的语义语言,并使用 [CATransaction begin] 和 [CATransaction commit] 等方法。在其他一切都是基于块的应用程序中间感觉很奇怪。

我认为您误读了文档。

基于块的动画是制作 UIView 动画的方式。时期。句号。

此语句不对应于 CoreAnimation。对于 CoreAnimation,您仍然必须使用 begin/commit。不要仅仅因为不推荐使用更高级别的构造 (UIView) 的 begin/commit 就假设 CA 开始和提交是不好的。

有没有办法将 CAMediaTimingFunctions 等概念与基于块的动画结合起来?

  • 如果您需要 Core Anmiation 的高级功能,例如自定义计时,您应该按照预期的方式使用 CoreAnimation(使用开始/提交等)
  • 如果您尝试为 CALayers 设置动画,请使用 Core Animation。
  • 如果您正在制作基于 UIView 的高级动画,请使用基于 UIView 块的动画。

【讨论】:

  • 这其实很有道理。
  • 真正的问题是不可能为基于 UIView 的动画指定计时函数。据我所知,您将面临一系列令人不快的选择:
  • @amatth 如何在特定时间添加水印。我的视频是 60 秒。我想添加 10 到 50 秒的水印。请帮帮我
【解决方案2】:

现在我要继续承认这看起来毫无意义,但这是我能想到的为您提供块界面的最快方法,它确实可以防止您意外地离开存在/提交

.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,你不觉得吗?
猜你喜欢
  • 2012-03-23
  • 2017-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多