我创建了一个NSView名为的子类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");
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我想使用这些DAView's添加/方法,我将面临同样的问题.一切都很好,除了drawRect:,在这种DAView情况下,从来没有被称为:
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");
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将DATableView标题更改为子类NSView,drawRect:则调用.我错过了什么?
来自文档:
"setWantsLayer:和setLayer:被调用的顺序很重要,它区分了图层支持的视图和图层托管视图."
"图层支持的视图是由Core Animation图层支持的视图.视图完成的任何绘图都缓存在支持图层中.您可以通过调用setWantsLayer来配置图层支持的视图:值为YES. class会自动为您创建一个支持层(如果被覆盖则使用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;
Run Code Online (Sandbox Code Playgroud)
或者,接受Cocoa给你的一个,不要创建自己的.
您必须将 的委托设置_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];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4742 次 |
| 最近记录: |