NSView子类 - drawRect:未调用

时间:2013-05-25 16:11:36

标签: objective-c cocoa

我创建了一个名为NSView的{​​{1}}子类,其中包含一系列有用的方法供以后重复使用。这很好用,但是DAView永远不会在任何使用drawRect:的类中调用,也不会在类本身中调用。为什么呢?

以下是DAView的样子:

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:的情况从未被调用过:

DATableView

DAView

@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的子类,则会调用NSView。 我错过了什么?

2 个答案:

答案 0 :(得分:9)

来自文档:

“调用setWantsLayer:和setLayer:的顺序非常重要,它区分了图层支持的视图和图层托管视图。”

“图层支持的视图是由Core Animation图层支持的视图。视图完成的任何绘图都缓存在支持图层中。您可以通过调用setWantsLayer来配置图层支持的视图:值为YES 。视图类自动为您创建一个支持层(如果被覆盖则使用makeBackingLayer),并且必须使用视图类的绘制机制。当使用图层支持的视图时,您不应该直接与图层交互。而是必须使用标准视图编程实践。“

“图层托管视图是一个包含您想要直接操作的Core Animation图层的视图。您可以通过实例化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;

或者,接受Cocoa给你的一个,不要自己创建。

答案 1 :(得分:4)

您必须将_rootLayer的代理设置为self

修改 它对我有用:

- (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];
}