【问题标题】:Color property in CALayer subclassCALayer 子类中的颜色属性
【发布时间】:2017-03-23 14:14:38
【问题描述】:

这让我发疯了。我正在尝试更改 CALayer 子类的自定义属性“mycolor”,这是我的代码:

#import "Circle"

@interface Circle()
   @property (nonatomic, strong) UIColor * mycolor;
   @property (nonatomic) float initial_angle;
   @property (nonatomic) float end_angle;
@end

@implementation Circle

@synthesize mycolor;
@synthesize initial_angle, end_angle;

- (id) init {
    self = [super init];
    if (self) {

        CGFloat red =  (CGFloat)random()/(CGFloat)RAND_MAX;
        CGFloat blue = (CGFloat)random()/(CGFloat)RAND_MAX;
        CGFloat green = (CGFloat)random()/(CGFloat)RAND_MAX;
        self.mycolor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
        self.backgroundColor =  [UIColor clearColor].CGColor;

    }
    return self;
}


-(void) changeColor {
    CGFloat red =  (CGFloat)random()/(CGFloat)RAND_MAX;
    CGFloat blue = (CGFloat)random()/(CGFloat)RAND_MAX;
    CGFloat green = (CGFloat)random()/(CGFloat)RAND_MAX;
    self.mycolor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
}

- (void) animate {
    float final = arc4random() % 360;
    float afrom = self.initial_angle;
    self.initial_angle = final;
    CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath:@"initial_angle"];
    anim.fromValue = [NSNumber numberWithFloat:afrom];
    anim.toValue = [NSNumber numberWithFloat:final];
    anim.duration = 5;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self addAnimation:anim forKey:@"initial_angle"];

    final = arc4random() % 360;
    afrom = self.end_angle;
    self.end_angle = final;
    anim = [CABasicAnimation animationWithKeyPath:@"end_angle"];
    anim.fromValue = [NSNumber numberWithFloat:afrom];
    anim.toValue = [NSNumber numberWithFloat:final];
    anim.duration = 5;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [self addAnimation:anim forKey:@"end_angle"];    

}

- (void) drawInContext:(CGContextRef)ctx {

    CGContextMoveToPoint(ctx, 50, 50);
    CGContextAddArc(ctx, 50, 50, 50, initial_angle*M_PI/180, end_angle*M_PI/180, 0);
    CGContextClosePath(ctx);
    NSLog(@"%@", self.mycolor);

    CGContextSetFillColorWithColor(ctx, self.mycolor.CGColor);   
    CGContextFillPath(ctx);

}

+ (BOOL)needsDisplayForKey:(NSString*)key {
    if ([key isEqualToString:@"initial_angle"]||
        [key isEqualToString:@"end_angle"]||
        [key isEqualToString:@"mycolor"]) {
        return YES;
    } else {
        return [super needsDisplayForKey:key];
    }
}

@end

changeColor 和 animate 是公共方法。 Animate 每秒被调用一次,并且每次用户点击 de circle 时都会调用 changeColor。

除了“drawInContext”中的 mycolor 始终为 null 之外,一切正常。不知道为什么。

【问题讨论】:

  • 您如何创建Circle 的实例?
  • 我相信你应该继承 + layer 方法,而不是 CALayer 的 init

标签: objective-c ios


【解决方案1】:

您是否尝试在设置 mycolor 后立即记录它的值?

您的代码看起来不错,所以肯定发生了一些奇怪的事情。您是否有可能在某处为 mycolor 创建了自定义 setter 或 getter 方法但没有正确实现?

我假设您使用的是 ARC - 您是否尝试过直接设置 mycolor ivar 而不是通过 setter? (在 ARC 中应该没问题 - 它不会泄漏或意外释放)

【讨论】:

  • 如果我在设置 mycolor 后记录它,就可以了。它仅在 drawInContext 中失败。但我刚刚发现它并不总是空的。有一个帧,当动画结束并再次开始之前,圆圈会随着颜色闪烁一毫秒,并记录颜色正常。所以我的猜测是它与我试图将颜色设置为模型层而不是表示层有关,那是动画层......??
  • 您是否考虑过使用 CAShapeLayer 代替这种方法?如果您尝试使用 CALayers 绘制一个充满颜色的动画多边形,我认为 CAShapeLayer 已经为您完成了所有工作。
  • 你的意思是继承 CAShapeLayer?
  • 是的,或者只是将其添加为圆形图层的子图层并直接使用。
  • CAShapeLayers 具有与 Core Graphics 类似的路径绘制方法和功能,但它们已经支持开箱即用的填充和描边颜色动画,并且性能明显优于使用 Core Graphics 绘制(我认为他们使用 OpenGL 绘制路径)。
【解决方案2】:
@synthesize mycolor = _mycolor;
_mycolor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];

尝试在 init 方法和 drawInContext 中使用 _mycolor。

    CGContextSetFillColorWithColor(ctx, self.mycolor.CGColor);   

我认为在 drawInContext 中你可以只使用实例变量而不是属性。

【讨论】:

    【解决方案3】:

    CALayer 的正确初始化程序是 +layer,您应该重写 +layer 方法,而不是可能根本不调用的 -init

    【讨论】:

      猜你喜欢
      • 2014-08-27
      • 2011-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 2023-03-10
      • 2023-01-24
      相关资源
      最近更新 更多