gpt4 book ai didi

ios - 使用带有 CAMediaTimingFunction 的 CADisplayLink 'combined' 为 UIView 设置动画。 (获得任意曲线)

转载 作者:可可西里 更新时间:2023-11-01 03:32:55 25 4
gpt4 key购买 nike

我正在使用 CADisplayLink 制作 View 动画,它只是插入一个值并重绘 View 本身。

例如我有一个 View MyView 并且它有一个属性 value,每当设置值时我调用 setNeedsDisplay 并且 View 知道要绘制什么。

为此设置动画,我使用 CADisplayLink 并且我希望 View 在值之间“变形”。我通过插入动画开始和停止值的值来做到这一点:

- (CGFloat)interpolatedValue:(CGFloat)sourceValue withValue:(CGFloat)targetValue forProgress:(CGFloat)progress;

现在获得线性进展很容易并获得“特定曲线”(好的)但我希望能够利用 CAMediaTimingFunction 来做到这一点(或其他一些预先存在的逻辑 - 我不'想重新发明轮子' :)

最佳答案

有这个很棒的要点 RSTiming这对你来说可能很方便。您可以使用标准 CAMediaTimingFunction 定义计时函数,甚至可以使用 2 个控制点定义贝塞尔曲线来定义自定义函数。

如果我得到了你的设置,你可能会有这样的东西:

View Controller

#import "ViewController.h"
#import "AnimatedView.h"
#include <stdlib.h>

@interface ViewController ()

@property (nonatomic, strong) CADisplayLink *displayLink;
@property (weak, nonatomic) IBOutlet AnimatedView *viewToAnimate;

@end

@implementation ViewController

- (void)viewDidLoad {
[super viewDidLoad];

self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFrame)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)updateFrame {
[self.viewToAnimate updateAnimation];
}

- (IBAction)updateAnimationTapped:(id)sender {
self.viewToAnimate.value = arc4random_uniform(101) / 100.0;
NSLog(@"Next animation value: %f", self.viewToAnimate.value);
}

@end

动画 View

#import "AnimatedView.h"
#import "RSTimingFunction.h"

@interface AnimatedView()
{
CGFloat _lastValue;
CGFloat _progressStep;
CGFloat _currentProgress;
}

@property (nonatomic, strong) RSTimingFunction *animationProgress;

@end

@implementation AnimatedView

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder]))
{
_progressStep = 0.01; // defines animation speed
_currentProgress = 1.0;
self.animationProgress = [RSTimingFunction timingFunctionWithName:kRSTimingFunctionEaseInEaseOut];
}

return self;
}

- (void)setValue:(CGFloat)value {
if (_value != value)
{
_lastValue = _value;
_value = value;
_currentProgress = 0.0;
}
}

- (void)updateAnimation
{
if (_currentProgress > 1.0)
return;

_currentProgress += _progressStep;
CGFloat currentAnimationValue = _lastValue + (_value - _lastValue) * [self.animationProgress valueForX:_currentProgress];

self.alpha = currentAnimationValue; // as an example animate alpha
}

@end

如前所述,您甚至可以设置 2 个控制点来创建以三次贝塞尔曲线为模型的计时函数。

self.animationProgress = [RSTimingFunction timingFunctionWithControlPoint1:CGPointMake(0.6, 0.6) controlPoint2:CGPointMake(0.1, 0.8)];

这将产生以下计时动画(使用 CAMediaTimingFunction playground 产生)

enter image description here

关于ios - 使用带有 CAMediaTimingFunction 的 CADisplayLink 'combined' 为 UIView 设置动画。 (获得任意曲线),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29938707/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com