You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:27:21