我在Mac OS X 10.6问题上有一个相对简单的Cocoa要问。我有一个主NSView
(实际上是ScreensaverView
),它不是图层支持的,否则就不起眼了。它通过drawRect
通过NSRectFill
和NSBezierPath:stroke
调用(基本上是点和线)来完成一些基本绘图。
我还有一个NSView
派生的子类,它充当子子视图。我这样做的目的是在子视图中绘制简单的线条,绘制在主视图中绘制的任何内容之上,但随后可以以某种方式“擦除”显示任何线条遮挡。这个子视图的代码非常简单:
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)drawRect:(NSRect)dirtyRect {
// Transparent background
[[NSColor clearColor] set];
NSRectFillUsingOperation(dirtyRect, NSCompositeCopy);
// If needed for this update, draw line
if (drawLine) {
// OMITTED: Code that sets opaque NSColor and draws a line using NSBezierPath:stroke
}
// If needed for this update, "erase" line
if (eraseLine) {
[[NSColor blackColor] set]; // clearColor?
// OMITTED: Code that draws the same line using NSBezierPath:stroke
}
}
使用上面显示的代码,只要子视图绘制,主视图就会变黑,您只能看到子视图行。未更新子视图时,主视图内容将再次出现。
我尝试过的事情,结果各不相同:
我尝试尝试让子视图从被覆盖的YES
返回isOpaque
(我意识到这不是真的正确)。当我这样做时,两个视图在子视图更新期间正确绘制,但是子视图行会覆盖它所绘制的任何内容(确定),然后在删除时,也会留下一条大黑线(我试图避免的)。尝试使用clearColor
代替blackColor
“删除”该行会导致该行保留在屏幕上。
我尝试通过调用[self setWantsLayer:YES]
中的init
同时制作两个(和/或只是子视图)图层支持的视图,这会导致完全黑屏。
我觉得我错过了一些非常基本的东西,但不管出于什么原因,我似乎无法弄明白。非常感谢任何和所有建议。
答案 0 :(得分:2)
我认为你从根本上误解了视图的工作原理。基本上,每次在视图上调用drawRect:
时,都会执行drawRect:
中的绘图命令。这可能会自动发生,也可能在您发出setNeedsDisplay:
消息时发生。
通常,在视图上调用drawRect:
时,视图将被删除并重新开始绘制。之前对drawRect:
的调用在视图中没有任何内容。您无需使用[NSColor clearColor]
填充视图,以使其透明。
请注意,只有当您的视图从NO
返回isOpaque
时才会出现这种情况,这是默认设置。如果您的观点从YES
返回isOpaque
,那么您需要确保在绘制前删除视图,但在特定情况下,您不应该从YES
返回isOpaque
因为你希望你的观点是透明的。
您无需“擦除”您绘制的线条。它会被删除。相反,当你不想绘制它时,你需要简单地不绘制它。
基本上,您的视图应该存储一些标记(例如名为BOOL
的{{1}} ivar或类似的东西。然后,在您的绘图代码中,您应该只检查是否设置了此值。如果是,你应该画线。如果没有,那就什么都不做。您的代码应该简化为:
drawLine
如果您想更改状态并重绘视图,您只需更改- (void)drawRect:(NSRect)rect
{
// If needed for this update, draw line
if (drawLine) {
// OMITTED: Code that sets opaque NSColor and draws a line using NSBezierPath:stroke
}
}
ivar的值并使用drawLine
要求视图重绘。
您可以使用计时器轻松完成此操作:
[yourView setNeedsDisplay:YES]