macOS视图NSView
macOS视图NSView

macOS视图NSView

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/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注