添加NSTrackingArea触发Unrecognised selector错误,如何获取NSPanel内NSImage鼠标坐标
问题根因
addTrackingArea:是NSView的专属实例方法,你将layer.contents赋值为NSImage类型实例,NSImage是资源类继承自NSObject,没有实现该方法,所以调用时直接触发无法识别选择器的运行时错误。- 直接给
NSPanel contentView添加跟踪区域获取到的是窗口坐标系坐标,需要做坐标系转换才能得到图片对应区域的相对坐标。
实现方案
方案1:使用NSImageView承载图片(推荐)
使用标准控件原生支持坐标转换,逻辑更清晰:
- 创建NSImageView承载你的图片,添加到NSPanel的contentView层级中:
// 替换为你实际的contentView、frame参数 NSImageView *imageView = [[NSImageView alloc] initWithFrame:contentView.bounds]; imageView.image = splitNSImage; [contentView addSubview:imageView];
- 给NSImageView添加跟踪区域:
NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseEnter | NSTrackingMouseExit | NSTrackingMouseMoved); NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:imageView.bounds options:options owner:self userInfo:nil]; [imageView addTrackingArea:trackingArea];
- 在鼠标移动事件中获取图片视图坐标系下的坐标:
- (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
相关产品推荐
相关产品推荐

