我有一个自定义CALayer,我试图在其中使用actionForKey并在this tutorial之后启用某些属性的动画。
我有一个CGFloat
属性,当在动画块中时,该属性会发生完美变化,而我的另一个属性UIColor
则不会。
这是我的职能:
- (id<CAAction>)actionForKey:(NSString *)event {
if ([self presentationLayer] != nil && [[self class] isCustomAnimationKey:event]) {
id animation = [super actionForKey:@"backgroundColor"];
if (animation == nil || [animation isEqual:[NSNull null]]) {
[self setNeedsDisplay];
return [NSNull null];
}
[animation setKeyPath:event];
[animation setFromValue:[self.presentationLayer valueForKey:event]];
[animation setToValue:nil];
return animation;
}
return [super actionForKey:event];
}
正在使用CGContextSetFillColorWithColor
设置颜色,但是我从日志中看到,颜色只是从一种颜色更改为另一种颜色,而没有任何内插值。
有什么想法吗?
答案 0 :(得分:1)
最后发现很明显,我需要在CALayer中公开一个CGColor
属性,并对其进行动画处理。
编辑:
这里有一些代码,以UIViewCustomPropertyAnimation项目为基础。
在OCLayer.h
中添加新属性:
@property (nonatomic) CGColorRef myColor;
在OCLayer.m
中添加@dynamic指令:
@dynamic myColor;
并更新isCustomAnimKey
:
+ (BOOL)isCustomAnimKey:(NSString *)key {
return [key isEqualToString:@"percent"] || [key isEqualToString:@"myColor"];
}
在OCView.h
中添加相同的属性,但将其作为UIColor
。这已经存在于我的项目中,因此不需要修改,这很棒,因为它没有破坏任何代码。
@property (nonatomic, strong) UIColor *progressColor;
主要更改将在OCView.m
中,因为获取器和设置器需要从CGColor
转换为UIColor
,然后再次返回。
- (void)setMyColor:(UIColor *)color {
self.layer.myColor = color.CGColor;
}
- (UIColor*)myColor {
return [UIColor colorWithCGColor: self.layer.myColor];
}
现在可以正常执行动画了:
[UIView animateWithDuration:1.f animations:^{
self.animView.myColor = [UIColor redColor];
}];
答案 1 :(得分:0)
这是我的代码,而不是答案。共有三类:OCLayer,OCView和OCViewController。您可以看到动画期间“百分比”的值正在变化,而“ myColor”的值却没有变化。
@interface OCLayer : CALayer
@property (nonatomic) CGFloat percent;
@property (nonatomic) CGColorRef myColor;
@end
#import "OCLayer.h"
@implementation OCLayer
@dynamic percent;
@dynamic myColor;
- (id<CAAction>)actionForKey:(NSString *)key
{
if ([[self class] isCustomAnimKey:key])
{
id animation = [super actionForKey:@"backgroundColor"];
if (animation == nil || [animation isEqual:[NSNull null]])
{
[self setNeedsDisplay];
return [NSNull null];
}
[animation setKeyPath:key];
[animation setFromValue: [self.presentationLayer valueForKey:key]];
[animation setToValue : nil];
return animation;
}
return [super actionForKey:key];
}
- (id)initWithLayer:(id)layer
{
self = [super initWithLayer:layer];
if (self)
{
if ([layer isKindOfClass:[OCLayer class]])
{
self.percent = ((OCLayer *)layer).percent;
}
}
return self;
}
+ (BOOL)needsDisplayForKey:(NSString *)key
{
if ([self isCustomAnimKey:key]) return true;
return [super needsDisplayForKey:key];
}
+ (BOOL)isCustomAnimKey:(NSString *)key
{
return [key isEqualToString:@"percent"] || [key isEqualToString:@"myColor"];
}
@end
@interface OCView : UIView
@property (weak, nonatomic) IBOutlet UIView *percentView;
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic, strong) UIColor * myColor;
//- (UIColor*)myColor ;
//- (void)setMyColor:(UIColor *)color;
- (CGFloat )percent;
- (void)setPercent:(CGFloat )percent;
@end
#import "OCView.h"
#import "OCLayer.h"
@implementation OCView
- (void)displayLayer:(CALayer *)layer
{
CGFloat percent = [(OCLayer *)[self.layer presentationLayer] percent];
CGColorRef myColor = [(OCLayer *)[self.layer presentationLayer] myColor];
NSLog(@"%f", percent);
NSLog(@"%@", myColor);
self.percentView.backgroundColor = [[UIColor alloc]initWithCGColor: myColor];
self.label.text = [NSString stringWithFormat:@"%.0f", floorf(percent)];
}
+ (Class)layerClass
{
return [OCLayer class];
}
- (void)setPercent:( CGFloat )percent
{
((OCLayer *)self.layer).percent = percent;
}
- (CGFloat )percent
{
return ((OCLayer *)self.layer).percent;
}
- (void)setMyColor:(UIColor *)color {
((OCLayer *)self.layer).myColor = color.CGColor;
}
- (UIColor*)myColor {
return [UIColor colorWithCGColor: ((OCLayer *)self.layer).myColor];
}
@end
@interface OCViewController : UIViewController
@property (weak, nonatomic) IBOutlet OCView *animView;
@end
#import "OCViewController.h"
#import "OCLayer.h"
@interface OCViewController ()
@end
@implementation OCViewController
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
self.animView.percent = 1;
self.animView.myColor = [UIColor whiteColor];
[UIView animateWithDuration:3.0
animations:^{
self.animView.percent = 20;
self.animView.myColor = [UIColor redColor];
}];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
@end