查找位于 NSPoint 位置下的最顶层 NSView 对象
Find the top-most NSView object located under NSPoint position
我知道这里已经以几种形式提出了这个问题,但不幸的是,没有一个建议的解决方案对我有用。
我正在实施我的 osx
应用的 多点触控 功能。
我的问题:
我需要解析屏幕上的一个位置,由 NSPoint
在屏幕坐标中描述,从我的应用程序 NSView
对象 位于此位置(如果有)下。
这有点像 HWND WindowFromPoint( Point)
下的 Windows
OS。
需要考虑的几点:
- 我的应用程序管理多个
NSWindow
,其中每个 window 包含多个 NSView
的层次结构,
- 我感兴趣的
NSView
不一定是应用程序 Key Window
或 Main Window
,因为它可以是我当前未激活的任何其他应用程序 NSView
恰好在此屏幕位置下的对象,
- 有可能在特定的
NSPoint
下,我会有不止一个 NSWindow
s and/or NSView
s。在这种情况下,我将只对最顶层的 NSView
、 感兴趣
- 有可能
NSView
A 在 NSView
B 之上,部分隐藏了它,但是 NSPoint
位置只出现在 B 上,不是最上面-most window 应用程序(但仅是此位置的最顶层)。在这里我又会对B感兴趣。
我成功完成的事情:
- 枚举
NSApp
的所有 windows (NSApp.windows
),
- 列举
NSWindow
的观点 (NSWindow.contentView.subviews
),
- 为其子视图枚举
NSView
(NSView.subviews
)
这样做我设法枚举了我的应用程序的所有 NSView
,但我仍然需要过滤掉不可见的不相关 NSView
。
不对我有用的东西:
NSView.hitTest
为有效位置返回 nil
,
NSView.layer.zPosition
始终为零 (0),
NSView.subviews
列表的顺序也不反映当前的 GUI 布局,
- 测试
NSView
是否可见也无济于事,因为它 returns 如果此 window 被其他 window 隐藏,则同样如此
我的环境:
Mac
、OSX El-Capitan
、XCode-7
、Cocoa
、Objective-C
感谢您的帮助!
PazO
找到了:
// 1. Get the Window-Number of the NSWindow object owning this point:
NSInteger wndNumber = [NSWindow windowNumberAtPoint:(point) belowWindowWithWindowNumber:(0)];
// 2. Get the NSWindow object associated with this particular Window-Number:
NSWindow* window = [NSApp windowWithWindowNumber:(wndNumber)];
// 3. Convert NSPoint values from System-coordinates to NSWindow-coordinates (Thanks @Willeke for his comment)
NSRect rctScreen;
rctScreen.origin = point;
rctScreen.size.height = rctScreen.size.width = 0;
NSRect rctWindow = [window convertRectFromScreen:rctScreen];
// 4. Now do the hitTest:
NSView* viewFound = [[window contentView] hitTest:rctWindow.origin];
显然,每一行都应该针对 nil
进行测试,但为了代码简洁,我将其省略。
我知道这里已经以几种形式提出了这个问题,但不幸的是,没有一个建议的解决方案对我有用。
我正在实施我的 osx
应用的 多点触控 功能。
我的问题:
我需要解析屏幕上的一个位置,由 NSPoint
在屏幕坐标中描述,从我的应用程序 NSView
对象 位于此位置(如果有)下。
这有点像 HWND WindowFromPoint( Point)
下的 Windows
OS。
需要考虑的几点:
- 我的应用程序管理多个
NSWindow
,其中每个 window 包含多个NSView
的层次结构, - 我感兴趣的
NSView
不一定是应用程序Key Window
或Main Window
,因为它可以是我当前未激活的任何其他应用程序NSView
恰好在此屏幕位置下的对象, - 有可能在特定的
NSPoint
下,我会有不止一个NSWindow
s and/orNSView
s。在这种情况下,我将只对最顶层的NSView
、 感兴趣
- 有可能
NSView
A 在NSView
B 之上,部分隐藏了它,但是NSPoint
位置只出现在 B 上,不是最上面-most window 应用程序(但仅是此位置的最顶层)。在这里我又会对B感兴趣。
我成功完成的事情:
- 枚举
NSApp
的所有 windows (NSApp.windows
), - 列举
NSWindow
的观点 (NSWindow.contentView.subviews
), - 为其子视图枚举
NSView
(NSView.subviews
)
这样做我设法枚举了我的应用程序的所有 NSView
,但我仍然需要过滤掉不可见的不相关 NSView
。
不对我有用的东西:
NSView.hitTest
为有效位置返回nil
,NSView.layer.zPosition
始终为零 (0),NSView.subviews
列表的顺序也不反映当前的 GUI 布局,- 测试
NSView
是否可见也无济于事,因为它 returns 如果此 window 被其他 window 隐藏,则同样如此
我的环境:Mac
、OSX El-Capitan
、XCode-7
、Cocoa
、Objective-C
感谢您的帮助!
PazO
找到了:
// 1. Get the Window-Number of the NSWindow object owning this point:
NSInteger wndNumber = [NSWindow windowNumberAtPoint:(point) belowWindowWithWindowNumber:(0)];
// 2. Get the NSWindow object associated with this particular Window-Number:
NSWindow* window = [NSApp windowWithWindowNumber:(wndNumber)];
// 3. Convert NSPoint values from System-coordinates to NSWindow-coordinates (Thanks @Willeke for his comment)
NSRect rctScreen;
rctScreen.origin = point;
rctScreen.size.height = rctScreen.size.width = 0;
NSRect rctWindow = [window convertRectFromScreen:rctScreen];
// 4. Now do the hitTest:
NSView* viewFound = [[window contentView] hitTest:rctWindow.origin];
显然,每一行都应该针对 nil
进行测试,但为了代码简洁,我将其省略。