我创建了一个名为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
。
我错过了什么?
答案 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];
}