NSView 是 macOS AppKit 框架中的基础视图类,等价于 iOS 中的 UIView,它是所有界面元素(按钮、图片、文本、自定义绘图等)的基类。

初始化NSView
1、NSView实例
在简单的场景中,可以使用NSView()初始化视图:
let v = NSView()
v.wantsLayer = true
v.layer?.backgroundColor = NSColor.red.cgColor
例如,显示背景色、添加按钮或图片等子视图,不需要自定义绘图或事件处理。
2、创建NSView并重写构造器:
在复杂的场景(绘制图形、响应鼠标点击或自定义控件):
class ScreenshotOverlayView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
子类化NSView时,需要实现构造器逻辑,还可以重写mouse等方法。
注意:required init也必须实现,详细请见《Swift完整初始化覆盖链》。
常用属性
1、frame:NSRect类型,视图在父视图中的位置和尺寸。
2、bounds:NSRect类型,自身坐标系统的范围。
3、superview:NSView?类型,父视图。
4、subviews:[NSView]类型,所有所有子视图。
5、window:NSWindow?类型,所属窗口。
6、layer:CALayer?类型,可选的图层,用于高级绘制和动画。
7、wantsLayer:Bool类型,是否启用图层支持。
8、isHidden:Bool类型,是否隐藏。
9、alphaValue:CGFloat类型,不透明度(0~1)。
10、toolTip:String?类型,鼠标悬停提示文本。
常用方法
NSView 是 macOS AppKit 中所有视图的基类,负责绘制、事件处理、布局等功能。它提供了大量方法,可以分为以下几个主要类别:
一、视图生命周期与初始化
1、init(frame: NSRect):使用指定 frame 初始化视图;
2、awakeFromNib():从 Nib 或 Storyboard 加载完成后调用;
3、updateLayer():使用 Core Animation 时更新图层内容;
4、viewDidMoveToSuperview():视图添加到 superview 时调用;
5、viewDidMoveToWindow():视图添加到 window 时调用。
二、绘制相关
1、draw(_ dirtyRect: NSRect):重写此方法进行自定义绘制;
2、setNeedsDisplay(_:):标记视图为“需要重绘”;
3、needsDisplay:是否需要重绘;
4、canDraw():是否可以绘制(通常用于延迟绘制);
5、display():强制立即绘制。
三、布局与尺寸
1、layout():自动布局时会调用此方法,可重写处理子视图布局;
2、setFrameSize(_:):改变视图大小;
3、setFrameOrigin(_:):改变视图位置;
4、resizeSubviews(withOldSize:):父视图大小改变时调用,重排子视图;
5、isFlipped:坐标系是否翻转(默认原点在左下角)。
四、鼠标与键盘事件(继承自 NSResponder)
1、mouseDown(with:):鼠标按下;
2、mouseUp(with:):鼠标抬起;
3、mouseDragged(with:):鼠标拖动;
4、mouseMoved(with:):鼠标移动。需要设置 tracking area;
5、rightMouseDown(with:):右键按下;
6、scrollWheel(with:):鼠标滚轮事件;
7、keyDown(with:):键盘按下事件;
8、acceptsFirstResponder:视图是否响应键盘事件。
五、光标与跟踪区域
1、ddTrackingArea(_:):添加鼠标跟踪区域;
2、removeTrackingArea(_:):移除跟踪区域;
3、updateTrackingAreas():重新配置跟踪区域,通常在 resize 时调用;
4、resetCursorRects():设置光标样式。
六、图层与动画
1、wantsUpdateLayer:返回 true 时,系统会调用 updateLayer() 而非 draw(_:);
2、makeBackingLayer():自定义图层;
3、animator():返回一个可动画更改属性的代理;
4、animations:设置自定义动画字典。
七、子视图管理
1、addSubview(_:):添加子视图;
2、removeFromSuperview():移除自身;
3、replaceSubview(_:with:):替换子视图;
4、isDescendant(of:):是否是某视图的子视图。
八、坐标转换
1、convert(_:to:) / convert(_:from:):坐标转换到其他视图;
2、convertPoint(_:fromView:):将点从某视图转换到当前视图;
3、convert(_ rect: NSRect, from view: NSView?):同上,用于矩形。
九、辅助功能(Accessibility)
1、isAccessibilityElement():是否是辅助功能元素;
2、accessibilityLabel、accessibilityValue 等:提供无障碍支持的信息。
十、其他实用方法
1、hitTest(_:):判断某个点是否命中视图;
2、viewWithTag(_:):通过 tag 查找子视图;
3、snapshot():获取视图快照(macOS 10.15+ 可使用 bitmapImageRepForCachingDisplay(in:));
4、menu(for:):返回特定位置的右键菜单。
5、updateConstraints():更新 Auto Layout 约束。
使用示例
自定义一个蓝色方块视图:
class MyCustomView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
self.wantsLayer = true
self.layer?.backgroundColor = NSColor.blue.cgColor
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// 自定义绘图逻辑(例如画线、画圆等)
}
}
添加到窗口或父视图中:
let myView = MyCustomView(frame: NSRect(x: 20, y: 20, width: 100, height: 100))
someSuperview.addSubview(myView)
使用场景
作为基础容器视图(装载子控件)。
自定义控件绘制(如画板、图表)。
响应鼠标和键盘事件。
布局管理(配合 Auto Layout 或 frame 计算)。
注意事项
坐标系统默认是左下角为原点,可以通过 isFlipped 设置成类似 iOS 的从左上角开始。
要启用图层功能(用于动画或更复杂的效果),需设置:
view.wantsLayer = true
相关文章
1、Swift完整初始化覆盖链:https://fangjunyu.com/2025/07/31/swift-%e5%ae%8c%e6%95%b4%e5%88%9d%e5%a7%8b%e5%8c%96%e8%a6%86%e7%9b%96%e9%93%be/
2、macOS UI控件父类NSResponder:https://fangjunyu.com/2025/07/03/macos-ui%e6%8e%a7%e4%bb%b6%e7%88%b6%e7%b1%bbnsresponder/