Представление Layer-hosting не отображается

У меня проблемы с представлением размещения слоев. Эта версия initWithFrame: работает так, как ожидалось (вид закрашен черным), при условии, что в Интерфейсном Разработчике выбран 'Wants Core Animation Layer':

- (id)initWithFrame:(NSRect)frame 
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        [self setWantsLayer:YES];
        [[self layer] setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];    
        [[self layer] setContents:[NSImage imageNamed:NSImageNameBonjour]];
    }
    return self;
}

Я хочу иметь возможность программно настроить представление, поэтому я хочу избавиться от зависимости от Interface Builder. Ниже представлена ​​вторая версия, предназначенная для этого. Это не работает. Представление останется того же цвета, что и родительское представление:

- (id)initWithFrame:(NSRect)frame 
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        CALayer *rootLayer = [CALayer layer]; //Added this line,
        [self setLayer:rootLayer];  //and this line only
        [self setWantsLayer:YES];
        [[self layer] setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];    
        [[self layer] setContents:[NSImage imageNamed:NSImageNameBonjour]];
    }
    return self;
}

Я скопировал код из документации и поискал в Интернете, и все примеры, которые я нашел, делали именно это, но это не работает!

Что я делаю неправильно?


person Benedict Cohen    schedule 18.07.2010    source источник


Ответы (2)


Проблема не в слоях, а в том, что в жизненном цикле представлений они инициализируются.

Если представление создается в коде и добавляется к окну, которое уже было нарисовано на экране, то для создания слоев можно использовать метод initWithFrame:. Однако это не сработает, если представление инициализируется из NIB. При инициализации из NIB метод initWithFrame: будет вызываться до полной инициализации родительского окна, в результате чего слои не отображаются. Когда окно сохраняется в NIB, awakeFromNib может использоваться вместо initWithFrame: для обеспечения правильной инициализации слоев.

Конечно, наличие двух точек в коде, где можно было бы создавать слои, некрасиво. viewDidMoveToSuperview вызывается в полезном месте в обоих вышеупомянутых случаях использования. В viewDidMoveToSuperview следует добавить проверки, чтобы гарантировать, что слои будут созданы только один раз.

(Мысленное примечание - если что-то не имеет смысла и вы чувствуете, что хотите спросить в Stack Overflow, это хороший знак, что вам нужно немного поспать.)

person Benedict Cohen    schedule 19.07.2010

Можете ли вы попробовать вызвать следующее в initWithFrame?

[layer setFrame:[self bounds]];
person Amber Haq Dixon    schedule 02.07.2013