macos - NSPopover 内的 NSView : Converting Coordinates

标签 macos cocoa nsview nspopover

上下文

P 为 NSPopover,view 为 NSView,它是包含在 P 中的 subview 。

我需要什么

我想获取 View 的框架并将其转换为屏幕坐标系。通常,您会这样做:

NSRect frameRelativeToWindow = [self convertRect:self.frame relativeToView:nil]; 
[self.window convertRectToScreen:frameRelativeToWindow];

但是,由于 view 位于 NSPopover 中,因此其 window 属性为 nil,上述方法将返回 NSZeroRect: [0, 0, 0, 0]

那么,如果 View 位于 NSPopover 中,如何在屏幕坐标中获取 View 的框架?

注释:

  1. NSPopover 在屏幕上可见。
  2. 我尝试将其框架转换为屏幕坐标的 View 不是 NSPopover 或其 contentView 的直接 subview 。所讨论的 View 实际上是 NSTableCellView 内的自定义 NSView,NSTableCellView 内的 NSTableView 内的 NSScrollView 内的 NSClipView。 ClipView 是 NSPopover 的 contentView 的直接 subview 。
  3. 在普通的 NSWindow 中,您可以获取任何 subview 并调用 [self window] 来获取包含的 NSWindow 对象。然而,在弹出窗口中执行此操作会返回 nil。

最佳答案

以下代码假设您有

  • 管理弹出 View 的 NSViewController 子类
  • View Controller 实现NSPopoverDelegate

正如 hamstergene 指出的,弹出窗口的窗口在显示之前才可用。
当调用 popoverWillShow: 委托(delegate)方法时,弹出窗口 View 的窗口应该是 _NSPopoverWindow 的实例(而不是 nil)。

- (void)popoverWillShow:(NSNotification *)notification
{
    NSWindow* popOverWindow = self.view.window;
    NSRect popoverRectInScreenCoords = [popOverWindow convertRectToScreen:self.view.frame];
    NSLog(@"Popover Rect in Screen Coords:%@", NSStringFromRect(popoverRectInScreenCoords));
}

更新
布莱恩(OP)在评论中发布了他的问题的解决方案。
问题不在于 NSPopover 本身。他的一些 subview 的 nil 窗口的实际原因是 NSTableView,它释放了不可见的 NSTableCellViews
作为一种解决方法,他在自定义的 NSTableCellView 子类中实现了 viewDidMoveToWindow。当viewDidMoveToWindow:被调用时,表格单元格 View 已经有一个可用于执行坐标转换的窗口。

关于macos - NSPopover 内的 NSView : Converting Coordinates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21325479/

相关文章:

objective-c - 如果它是自定义类,则获取 NSViewController View ?

Eclipse 在 MacOS 上意外退出

linux - mac : using . 配置文件自定义命令

xcode - 如何反转选定 NSTableView 行的文本颜色

objective-c - 比较两个 NSMutableDictionaries

objective-c - NSTextView 不会更新,除非我点击它,并且它不会聚焦。有任何想法吗?

objective-c - 无法为某些 View 设置标签

objective-c - NSScrollView 在 Cocoa 中不滚动且 contentView 大小不正确

c++ - MacOS Sierra - cmake 因 qt5 而失败

cocoa - NSView 通过 NSTextView 接收点击事件