在Objective-C中如何指定绘图目标NSView?
嘿,这个问题问到点子上了——Cocoa的绘图逻辑其实是和NSView紧密绑定的,我给你拆解两种最常用的指定绘图目标的方式:
一、标准做法:给目标NSView写子类重写
drawRect: 这是Cocoa绘图的官方推荐流程,每个NSView只负责绘制自己的内容,所以你想在哪个View上画,就给那个View创建子类:
- 假设你有两个NSView实例:
viewA和viewB - 给需要绘图的那个View(比如
viewA)创建子类,重写drawRect:方法:
#import <Cocoa/Cocoa.h> @interface CustomDrawView : NSView @end @implementation CustomDrawView - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; // 在这里写你的矩形绘制代码,比如画一个红色矩形 NSRect targetRect = NSMakeRect(20, 20, 100, 100); [[NSColor redColor] setFill]; NSRectFill(targetRect); } @end
- 之后在Storyboard/XIB里把
viewA的类设置为CustomDrawView,或者在代码里初始化这个子类实例作为viewA。运行后只有viewA会显示红色矩形,viewB不受影响。
二、动态指定目标:手动切换绘图上下文
如果不想写子类,或者需要在运行时临时决定画到某个View上,可以通过NSGraphicsContext手动切换绘图上下文:
- 核心是锁定目标View的绘图焦点,确保后续绘图操作指向它:
// 假设你已经通过IBOutlet或代码拿到了viewA和viewB的引用 // 现在要画到viewB上 [viewB lockFocus]; // *必须先锁定焦点*,确保绘图上下文正确指向viewB // 开始绘制矩形 NSRect blueRect = NSMakeRect(50, 50, 80, 80); [[NSColor blueColor] setFill]; NSRectFill(blueRect); [viewB unlockFocus]; // 绘图完成后一定要解锁焦点
- 注意:这种方式尽量少用,因为脱离
drawRect:的绘图不会自动响应View的刷新(比如窗口大小变化),如果需要刷新,得手动调用[viewB setNeedsDisplay:YES]触发重绘。
小提醒
- 永远不要在非
drawRect:方法里随意绘图,除非你明确知道自己在管理绘图上下文,否则容易出现绘制内容消失、不更新的问题。 - 如果要更新某个View的内容,调用
[targetView setNeedsDisplay:YES],系统会自动调用它的drawRect:方法完成重绘。
内容的提问来源于stack exchange,提问作者Sentos
相关产品推荐
相关产品推荐

