zou*_*oul 2 cocoa-touch core-animation uiview ios
我有一个UIView绘制自己使用-drawRect:,我想动画用于绘图的颜色.UIView由于显而易见的原因,基本的动画内容不起作用(drawRect).
我不能简单地使用CAShapeLayer绘制和动画视图内容.我想尝试手动伪造动画,使用计时器或CADisplayLink结合使用setNeedsDisplay.是否有一种相当简单的方法来隐藏通常的UIView动画API 背后的魔力?
例如,假设有一个color我想要动画的属性:
[UIView animateWithDuration:0.2 animations:^{
[customDrawingView setColor:[UIColor redColor]];
}];
Run Code Online (Sandbox Code Playgroud)
有没有办法"拦截"动画调用来读取动画参数(时间,目标值)并手动处理它们?我不想慌乱UIView.
我不得不像你那样做了很多次.一般来说,您可以创建一些类来处理浮点插值或CGPoint插值等内容......并且正确地完成所有操作,但由于整个绘图已经存在,因此它没有多大意义.
所以UIView animateWithDuration这里不起作用,但您可以添加显示链接并手动进行插值.如果没有更改现有代码,最好只添加几个方法:
假设您目前有这样的事情:
- (void)setColor:(UIColor *)color
{
_color = color;
[self setNeedsDisplay];
}
Run Code Online (Sandbox Code Playgroud)
现在您可以添加setColorAnimated:并执行所有其他功能:
您需要一些额外的参数(属性),使用您想要的:
UIColor *_sourceColor;
UIColor *_targetColor;
NSDate *_startDate;
NSDate *_endDate;
CADisplayLink *_displayLink;
Run Code Online (Sandbox Code Playgroud)
方法:
- (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]];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1605 次 |
| 最近记录: |