将NSPoint从窗口坐标转换为视图坐标

Rog*_*ger 14 cocoa nsview nswindow

我的应用程序有一个自定义视图,显示事件的时间轴.此视图包含在一个NSScrollView支持水平滚动时间轴的位置.使用通知,我已经实现了一种机制,该机制应该显示另一个自定义视图,当用户在时间轴中单击该事件时,该视图显示有关事件的详细信息.以下是在时间轴收到事件时处理事件的代码:

NSEvent *anEvent = [aNotification object];
NSPoint aLocationInSelf = [self convertPoint: [anEvent locationInWindow] toView: self];

// Create callout view and display
NSRect aRect = NSMakeRect(aLocationInSelf.x, aLocationInSelf.y, 300, 200);
TimelineCallout *aCallout = [[TimelineCallout alloc] initWithFrame: aRect];
[self addSubview: aCallout];
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我将事件所记录的鼠标点击点从窗口坐标转换为视图(时间轴)坐标.

但是,当我使用调试器逐步完成此操作时,没有进行任何转换,并locationInSelf显示与我得到的点相同的坐标[anEvent locationInWindow].结果,标注被绘制在错误的位置或根本不可见.

我一定是做错了但是我弄不清楚是什么......

Lau*_*ble 27

要从窗口坐标转换为视图坐标,您必须使用:

NSPoint aLocationInSelf = [self convertPoint: [anEvent locationInWindow] fromView: nil];
Run Code Online (Sandbox Code Playgroud)

这将从窗口基坐标转换为接收器坐标,因为事件不是源自特定视图.

有关更多信息,请参阅文档.

更详细的解释:

转换方法有点难以理解.主要有两种情况(其他是变体):

  1. 当一个点位于同一窗口中时,将点从一个视图转换为另一个视图
  2. 将窗口坐标表示的点转换为视图坐标

对于第一种情况,您有两个位于同一窗口中的视图(view1和view2).如果要将view2中的点转换为view1的坐标系,代码将为:

NSPoint pointInView1 = [view1 convertPoint:pointInView2 fromView:view2];
Run Code Online (Sandbox Code Playgroud)

对于第二种情况,您有一个用窗口坐标表示的点(来自事件).由于该点以窗口坐标表示,因此您不指定"从"视图,代码将为:

NSPoint pointInView1 = [view1 convertPoint:pointInWindow fromView:nil];
Run Code Online (Sandbox Code Playgroud)

这是该方法的回退行为.