Подслой рисуется только при создании в initWithFrame, а не в initWithCoder

У меня есть пользовательский вид с подслоем (CAShapeLayer) и подвидом (UILabel). Когда я создаю слой в initWithCoder и устанавливаю цвет фона, он всегда отображается черным. Однако, если я перемещу код в initWithFrame, цвет будет успешно отображаться.

Разве мы не должны создавать подслои в initWithCoder?

Вот единственный способ заставить мой код работать:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.colorLayer = [CAShapeLayer layer];
        self.colorLayer.opacity = 1.0;
        [self.layer addSublayer:self.colorLayer];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {

        self.textLabel = [[UILabel alloc] initWithFrame:self.bounds];
        self.textLabel.font = [UIFont primaryBoldFontWithSize:12];
        self.textLabel.textColor = [UIColor whiteColor];
        self.textLabel.textAlignment = NSTextAlignmentCenter;
        self.textLabel.backgroundColor = [UIColor clearColor];
        [self addSubview:self.textLabel];
    }

    return self;

}

- (void)drawRect:(CGRect)rect {
    //Custom drawing of sublayer
}

ОБНОВЛЕНИЕ:

Оказывается, в моем drawRect я неправильно устанавливал цвет заливки. Я должен был использовать colorLayer.fillColor = myColor.CGColor вместо [myColor setFill], затем [path fill]


person dmoss18    schedule 18.08.2014    source источник


Ответы (1)


Разница между initWithFrame: и initWithCoder: заключается в том, что initWithCoder: вызывается, когда представление создается из раскадровки/сниба.

Если вы добавите его программно, например:

UIView *v = [[UIView alloc] initWithFrame:...];
[self.view addSubview:v];

initWithFrame: называется.

Хорошая идея — создать базовый метод инициализации и вызывать его как в init. Таким образом, инициализация устанавливает все свойства в обоих сценариях, когда представление добавляется программно или в раскадровке.

Например:

-(void)baseInit {
    self.colorLayer = [CAShapeLayer layer];
    self.colorLayer.opacity = 1.0;
    //... other initialisation
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self baseInit];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {

        [self baseInit];
    }

    return self;
}
person Greg    schedule 18.08.2014
comment
Но когда я создаю подслой И ulabel в одном и том же месте (например, initWithCoder), фон подслоя ВСЕГДА черный. Я не понимаю, почему это происходит. Кроме того, очевидно, initWithFrame никогда не вызывается, но подуровень все еще инициализируется. Это не имеет смысла, если то, что вы говорите, правда. - person dmoss18; 18.08.2014
comment
Если вы не верите, просто добавьте журнал к обоим этим инициализациям, и вы увидите, что будет вызван только один. Попробуйте добавить слой в вид, а после этого добавить слой метки в подслой: [self.colorLayer addSublayer:self.textLabel.layer]; [self.layer addSublayer:self.colorLayer]; - person Greg; 18.08.2014