macOS鼠标光标NSCursor
macOS鼠标光标NSCursor

macOS鼠标光标NSCursor

NSCursor 是 macOS AppKit 框架中用于表示和管理鼠标光标的类。它提供了对当前光标的控制,包括:

1、设置鼠标的外观(比如箭头、手型、I-beam 等);

2、显示/隐藏鼠标;

3、创建自定义鼠标光标;

4、查询当前正在使用的鼠标光标。

初始化方法

init(image: NSImage, hotSpot: NSPoint)

创建一个自定义鼠标指针。

let image = NSImage(named: "MyCursor")!
let hotSpot = NSPoint(x: 10, y: 10) // 鼠标点击点相对图片的位置
let myCursor = NSCursor(image: image, hotSpot: hotSpot)

只有在自定义鼠标指针时,才会使用初始化方法。

通常设置内置光标样式,使用set()、push()等方法修改当前指针的样式。

常见属性

1、获取当前光标:NSCursor.current。

2、调整大小光标:resizeLeftRight / resizeUpDown。

3、获取光标使用的 NSImage:image;

NSCursor.current.image	// 返回NSImage图像

注意:image方法返回NSCursor光标对象的图像,不是当前光标的图像

let cursorImage = NSCursor.crosshair.image

NSCursor.current 无法获得全局真实光标图像,macOS 并没有公开 API 允许开发者获取系统当前正在显示的真实光标图像(包括变形过的、来自别的 App 的样式)。因此,无法准确的获取当前全局光标样式图像,也就意味着无法获取当前鼠标光标的样式图像。

4、获取光标图像中的“热点”位置(即点击位置):hotSpot;

let hotSpot = NSCursor.current.hotSpot
print("hotSpot:\(hotSpot)")		// hotSpot:(4.0, 4.0)

这个hotSpot表示光标图像的左下角向右偏移4点,向上偏移4点的位置是光标真正的点击位置。

5、默认箭头(光标样式):NSCursor.arrow;

6、文本光标(光标样式):NSCursor.iBeam;

7、十字线(光标样式):NSCursor.crosshair;

8、链接手型(光标样式):NSCursor.pointingHand;

9、开放手型(光标样式):NSCursor.openHand;

10、闭合手型(光标样式):NSCursor.closedHand;

11、拒绝手型(光标样式):NSCursor.operationNotAllowed。

常用方法

1、set():设置当前鼠标为该光标,仅当前事件周期;

2、push():推入当前光标栈(设置光标并保存前一个);

3、pop():弹出并恢复上一个光标(配合 push());

4、hide() :隐藏鼠标指针(适合游戏/全屏应用);

5、unhide() :恢复鼠标显示;

使用场景

1、获取当前鼠标光标

let currentCursor = NSCursor.current

2、更改光标

NSCursor.crosshair.set()

3、创建自定义光标

let image = NSImage(named: NSImage.Name("CustomCursor"))!
let point = NSPoint(x: 10, y: 10) // 热点位置
let customCursor = NSCursor(image: image, hotSpot: point)
customCursor.set()

4、隐藏/显示鼠标

NSCursor.hide()
NSCursor.unhide()

总结

NSCursor可以控制鼠标样式,如果需要在悬停时修改鼠标样式。

NSCursor的set()、push()、pop()方法,类似数组的插入操作,通过该方法可实现改变光标以及恢复光标:

NSCursor.crosshair.push()
// 执行某个操作,比如绘图
// ...
NSCursor.pop() // 恢复之前的光标

如果只是临时修改光标,直接用 set(),如果想要改变后恢复光标,使用 push() / pop(),自定义光标就使用 init(image:hotSpot)方法,在全屏游戏/适配播放时,可使用 hide() / unhide() 控制鼠标的显示/隐藏。

当设置cursor.set() 后,只有在当前事件循环内生效,如果鼠标移出应用、进入其他控件或者视图被刷新时,可能会被系统或 AppKit 自动恢复,相关案例请见《SwiftUI onHover无法修改鼠标样式的问题》。

相关文章

1、SwiftUI修改鼠标光标/指针样式:https://fangjunyu.com/2025/07/09/swiftui%e4%bf%ae%e6%94%b9%e9%bc%a0%e6%a0%87%e5%85%89%e6%a0%87-%e6%8c%87%e9%92%88%e6%a0%b7%e5%bc%8f/

2、SwiftUI onHover无法修改鼠标样式的问题:https://fangjunyu.com/2025/07/09/swiftui-onhover%e6%97%a0%e6%b3%95%e4%bf%ae%e6%94%b9%e9%bc%a0%e6%a0%87%e6%a0%b7%e5%bc%8f%e7%9a%84%e9%97%ae%e9%a2%98/

扩展知识

hotSpot是什么?

在常见属性中,使用hotSpot获取点击位置:

let hotSpot = NSCursor.current.hotSpot
print("hotSpot:\(hotSpot)")		// hotSpot:(4.0, 4.0)

但实际上NSCursor.current鼠标样式是箭头,所以点击位置应该是左上角,例如AppKit左边从左下角计算,那么点击位置应该是 (0.0, 4.0),而不是右上的 (4.0,4.0)。

为了探索hotSpot点击位置,我们使用NSImage输出鼠标光标图像的尺寸:

print(NSCursor.current.image.size)  // (17.0, 23.0)

这是macOS的逻辑尺寸(point),不是像素点。

当我们通过NSCursor.current.image获取鼠标光标的图像时,图像的尺寸为:

170, 230

导出的图像尺寸在保存过程中被扩大了10倍。

按照10倍尺寸,可以找到hotSpot为40,40。

因此,左上角为原点,向右下偏移40,40像素,就是点击热点。

奇怪的是,AppKit原点实际上从左下角开始计算,但是这里的点击热点是从左上角为原点计算的,但是Apple文档也是从左上角计算的:

热点精确地决定了光标图像内的点击位置。使用其翻转坐标系,您可以以左上角为原点,以点为单位计算热点。例如,箭头光标的热点位于其左右边缘的交点处,该交点距离图像角 4pt,用于计算箭头的笔触和阴影。

相关文档请见《Apple Developer文档 hotSpot》。

   

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

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

发表回复

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