5

我创建了一个NSView名为 的子类DAView,其中包含一组有用的方法以供以后重用。这很好用,但是,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 的情况下,它永远不会被调用:

数据表视图

@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' 的标题更改为 , 的子类NSViewdrawRect:则会调用。我错过了什么?

4

2 回答 2

10

从文档:

“调用 setWantsLayer: 和 setLayer: 的顺序很重要,它区分了 layer-backed view 和 layer-hosting view。”

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

“图层托管视图是包含您打算直接操作的核心动画层的视图。您通过实例化核心动画图层类并将该图层提供给视图的 setLayer: 方法来创建图层托管视图。这样做之后, 然后调用 setWantsLayer: 值为 YES。此方法顺序至关重要。使用 layer-hosting view 时,不应依赖视图进行绘图,也不应将子视图添加到 layer-hosting view。根层(使用 setLayer 设置的层:)应该被视为层树的根层,您应该只使用 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 给你的那个,不要创造你自己的。

于 2013-05-25T17:21:09.803 回答
4

您必须将委托设置_rootLayerself

编辑 它对我的工作原理:

- (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];
}
于 2013-05-25T16:24:31.740 回答