2013-05-25 2 views
4

Я создал подкласс NSView под названием DAView, содержащий множество полезных методов для последующего повторного использования. Это отлично работает, однако drawRect: никогда не вызывается ни в одном классе, который использует DAView, ни в самом классе. Зачем?Подкласс NSView - drawRect: не называется

Вот как DAView выглядит следующим образом:

DAView

@interface DAView : NSView

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 

    if (self) 
    { 
     self.backgroundColor = [NSColor clearColor]; 

     // Make layer-backed by default 
     self.wantsLayer = YES; 

     // Create a root layer 
     CALayer *_rootLayer = [CALayer layer]; 

     _rootLayer.shouldRasterize = YES; 

     _rootLayer.name = DAViewRootLayerDefaultName; 

     self.layer = _rootLayer; 
    } 

    return self; 
} 

- (void)drawRect:(NSRect)dirtyRect // never called 
{ 
    NSLog(@"Draw Rect called"); 
} 

Теперь, если я хотел бы сделать использование этого DAView's дополнения/методов, я сталкиваюсь с той же проблемой. Все работает отлично, за drawRect: исключением, что, как и в DAView 'случае s, никогда не называют:

DATableView

@interface DATableView : DAView

- (void)drawRect:(NSRect)dirtyRect // never called either 
{ 
    [[NSColor grayColor] set]; 

    NSBezierPath *_cellSeparator = [NSBezierPath bezierPath]; 

    [_cellSeparator lineToPoint:dirtyRect.origin]; 

    [_cellSeparator closePath]; 

    [_cellSeparator stroke]; 

    NSLog(@"Draw rect"); 
} 

Однако если я изменить DATableView' заголовок s быть подкласс NSView, drawRect:. Что мне не хватает?

ответ

4

Вам необходимо установить делегат от _rootLayer до self.

EDIT Как это работает для меня:

- (id)initWithFrame:(NSRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.wantsLayer = YES; 
     self.layer = [self makeBackingLayer]; 
     [self.layer setDelegate:self]; 
    } 

    return self; 
} 

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { 
    NSRect rect = self.bounds; 
    rect.origin.x = 0; 
    rect.origin.y = 0; 
    [self drawRect:rect]; 
} 
+0

Это не имеет значения, и я думаю, что это не может быть ответ. 'NSView', в отличие от' UIView', по умолчанию не имеет свойства 'wantLayer',' YES', но 'drawRect:' по-прежнему вызывается (за исключением моего случая по какой-либо причине), даже без слоя в качестве основы магазин. – Pripyat

+0

ваш drawrect не вызывается даже без поддержки слоя? Чем я думаю, ваша проблема не появляется в вашем коде. –

+0

'drawRect:' называется без поддержки слоя - извините! Но с моим слоем, это не ... как я могу объединить эти два? – Pripyat

8

Из документов:

«Порядок, в котором setWantsLayer: и setLayer: называются важно, это делает различие между слоем -backed view и вид размещения на уровне слоев. "

«Вид с поддержкой слоя - это представление, поддерживаемое слоем базовой анимации. Любой чертеж, выполненный с помощью представления, кэшируется на уровне подложки. Вы настраиваете представление с поддержкой слоя, вызывая setWantsLayer: со значением ДА. Класс вида автоматически создает для вас слой поддержки (используя makeBackingLayer, если он переопределен), и вы должны использовать механизмы рисования класса представления. При использовании представлений с поддержкой слоев вам никогда не следует напрямую взаимодействовать со слоем. Вместо этого вы должны использовать стандартный просматривать методы программирования ».

«Слой-хостинг - это представление, которое содержит слой основной анимации, который вы намереваетесь манипулировать напрямую. Вы создаете представление уровня размещения, создавая класс класса Core Animation и предоставляя этот слой методу setLayer: После этого вы вызываете setWantsLayer: со значением YES. Этот порядок методов имеет решающее значение. При использовании представления на уровне слоев вы не должны полагаться на представление для рисования, а также не должны добавлять субвью в представление уровня размещения Корневой слой (слой, устанавливаемый с помощью setLayer :), должен рассматриваться как корневой слой дерева слоев, и вы должны использовать только методы рисования и анимации Core Animation. Вы все еще используете представление для обработки событий мыши и клавиатуры, но любые результирующие рисунок должен обрабатываться Core Animation. "

Поскольку вы поставляете свой собственный слой, а не хотите, чтобы Cocoa создавал его для вас, попробуйте его таким образом.

// Create a root layer 
    CALayer *_rootLayer = [CALayer layer]; 

    _rootLayer.shouldRasterize = YES; 

    _rootLayer.name = DAViewRootLayerDefaultName; 

    self.layer = _rootLayer; 

    // Make layer-backed by default 
    self.wantsLayer = YES; 

В качестве альтернативы, признайте, что один какао дает вам и не создавайте свои собственные.

Смежные вопросы