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

添加NSTrackingArea触发Unrecognised selector错误,如何获取NSPanel内NSImage鼠标坐标

问题根因

  • addTrackingArea: 是NSView的专属实例方法,你将layer.contents赋值为NSImage类型实例,NSImage是资源类继承自NSObject,没有实现该方法,所以调用时直接触发无法识别选择器的运行时错误。
  • 直接给NSPanel contentView添加跟踪区域获取到的是窗口坐标系坐标,需要做坐标系转换才能得到图片对应区域的相对坐标。

实现方案

方案1:使用NSImageView承载图片(推荐)

使用标准控件原生支持坐标转换,逻辑更清晰:

  1. 创建NSImageView承载你的图片,添加到NSPanel的contentView层级中:
// 替换为你实际的contentView、frame参数
NSImageView *imageView = [[NSImageView alloc] initWithFrame:contentView.bounds];
imageView.image = splitNSImage;
[contentView addSubview:imageView];
  1. 给NSImageView添加跟踪区域:
NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseEnter | NSTrackingMouseExit | NSTrackingMouseMoved);
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:imageView.bounds options:options owner:self userInfo:nil];
[imageView addTrackingArea:trackingArea];
  1. 在鼠标移动事件中获取图片视图坐标系下的坐标:
- (void)mouseMoved:(NSEvent *)event {
    // imageView为你承载图片的NSImageView实例
    NSPoint locationInImage = [imageView convertPoint:event.locationInWindow fromView:nil];
    // 若需映射到图片实际像素坐标,可结合图片缩放比例做二次换算即可
}

方案2:保留原layer实现的适配方案

如果不想使用NSImageView,可直接给contentView添加跟踪区域,手动做坐标系转换:

- (void)mouseMoved:(NSEvent *)event {
    // 先把窗口坐标转为contentView坐标
    NSPoint viewPoint = [contentView convertPoint:event.locationInWindow fromView:nil];
    // 再转为layer内部坐标系坐标
    NSPoint layerPoint = [layer convertPoint:viewPoint fromLayer:contentView.layer];
    // layerPoint即为你设置的图片对应区域的相对坐标
}

内容的提问来源于stack exchange,提问作者Arthur Rees

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:24:03