gpt4 book ai didi

ios - 使用 drawRect 伪造 UIView 动画

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:27:06 26 4
gpt4 key购买 nike

我有一个 UIView,它使用 -drawRect: 自行绘制,我想为绘图使用的颜色设置动画。由于显而易见的原因 (drawRect),基本的 UIView 动画内容无法正常工作。

我不能简单地使用 CAShapeLayer 来绘制和动画 View 内容。我想尝试使用计时器或 CADisplayLink 结合 setNeedsDisplay 手动伪造动画。有没有一种相当简单的方法可以将这种魔力隐藏在通常的 UIView 动画 API 后面?

例如,假设有一个 color 属性我想设置动画:

[UIView animateWithDuration:0.2 animations:^{
[customDrawingView setColor:[UIColor redColor]];
}];

有没有办法“拦截”动画调用读取动画参数(时间、目标值)并手工处理?我不想调整 UIView

最佳答案

我不得不像你一样做很多次。一般来说,您可以创建一些类来处理诸如浮点插值或 CGPoint 插值之类的东西...并正确地完成所有操作,但由于整个绘图已经存在,因此没有太多意义。

因此 UIView animateWithDuration 在这里不起作用,但您可以添加显示链接并手动进行插值。如果不更改现有代码,最好只添加几个方法:

假设你现在有这样的东西:

- (void)setColor:(UIColor *)color
{
_color = color;
[self setNeedsDisplay];
}

现在您可以添加 setColorAnimated: 并执行所有附加功能:

你需要一些额外的参数(属性),使用你想要的:

UIColor *_sourceColor;
UIColor *_targetColor;
NSDate *_startDate;
NSDate *_endDate;
CADisplayLink *_displayLink;

和方法:

- (void)setColorAnimated:(UIColor *)color {
_sourceColor = self.color; // set start to current color
_targetColor = color; // destination color
_startDate = [NSDate date]; // begins currently, you could add some delay if you wish
_endDate = [_startDate dateByAddingTimeInterval:.3]; // will define animation duration

[_displayLink invalidate]; // if one already exists
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(onFrame)]; // create the display link
}
- (UIColor *)interpolatedColor:(UIColor *)sourceColor withColor:(UIColor *)targetColor forScale:(CGFloat)scale {
// this will interpolate between two colors
CGFloat r1, g1, b1, a1;
CGFloat r2, g2, b2, a2;
[sourceColor getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
[targetColor getRed:&r2 green:&g2 blue:&b2 alpha:&a2];

// do a linear interpolation on RGBA. You can use other
return [UIColor colorWithRed:r1+(r2-r1)*scale
green:g1+(g2-g1)*scale
blue:b1+(b2-b1)*scale
alpha:a1+(a2-a1)*scale];
}
- (void)onFrame {
// scale is valid between 0 and 1
CGFloat scale = [[NSDate date] timeIntervalSinceDate:_startDate] / [_endDate timeIntervalSinceDate:_startDate];
if(scale < .0f) {
// this can happen if delay is used
scale = .0f;
}
else if(scale > 1.0f)
{
// end animation
scale = 1.0f;
[_displayLink invalidate];
_displayLink = nil;
}
[self setColor:[self interpolatedColor:_sourceColor withColor:_targetColor forScale:scale]];
}

关于ios - 使用 drawRect 伪造 UIView 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26751897/

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