代码之家  ›  专栏  ›  技术社区  ›  Leon

我如何在一个容器中制作uicolor动画?

  •  0
  • Leon  · 技术社区  · 7 年前

    我有一个自定义的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 但我可以从日志中看到,颜色只是从一个变化到下一个,没有任何插值值。

    有什么想法吗?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Leon    7 年前

    结果很明显,我需要揭露 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 因为getter和setter需要从 CG颜色 ui颜色 又回来了。

    - (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];
    }];
    
        2
  •  0
  •   E.Coms    7 年前

    这是我的密码,不是答案。有三个类: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