获取自定义 NSTableCellView 在 NSTableView 中的位置
Getting position of custom NSTableCellView within NSTableView
我正在尝试将 NSPopover 添加到 NSTableView 中的自定义 NSTableCellView。我能够让 NSPopover 出现对应于正确的元素,但弹出窗口的位置不正确。为了弄清楚我的问题,以防有人对设计提出更好的建议:当用户将鼠标悬停在 table 个联系人中的联系人上时,我想在弹出窗口中显示该联系人的更多信息(无需点击)
目前NSPopover初始化如下:
contactPopover = NSPopover(contentViewController: contactViewController, sender: allContactsViewController.view, bounds: contactTableCellView.frame)
该初始化程序只是轻轻地设置弹出行为并调用 popover.show(...)
其中 contactTableCellView 是我想要的联系人的 table 单元格视图。
问题是 contactTableCellView.frame
总是有 (x,y) = (0,0) 可能是因为这是自定义 NSTableCellView 的模板在 xib 中开始的地方。要将弹出窗口正确放置在 table 上,我需要获取 table 单元格视图相对于 NSTable 原点的位置。
现在每个 NSTableCellView 都有鼠标跟踪设置,所以在鼠标输入时,我通知联系人列表显示弹出框,我在其中传递相应的鼠标输入 table 单元格视图。这使我在尝试获取相对于 table 的位置时可以访问 table 单元格视图,但我在文档中找不到任何关于如何获取 [=] 的真实位置的信息25=] 相对于 table 原点的单元格视图。
看过:https://developer.apple.com/reference/appkit/nstableview
https://developer.apple.com/reference/appkit/nstablecellview
我不确定这是关于什么的:
contactPopover = NSPopover(contentViewController: contactViewController, sender: allContactsViewController.view, bounds: contactTableCellView.frame)
那个方法是从哪里来的?它不是 NSPopover
本身的一部分。
无论如何,假设创建的弹出窗口没有多余的包袱,这应该可以满足您的需求:
contactPopover.show(relativeTo:contactTableCellView.bounds of:contactTableCellView preferredEdge:.minY)
这将使弹出窗口相对于单元格视图定位,而无需弄清楚单元格视图在 table 视图中的位置。
离开与@KenThomases 的会议,其中最好的方法是让 table 视图单元格本身管理弹出窗口,但这只是 half-possible。我来解释一下:
自从 table 重新绘制 table 单元格视图后,contactTableCellView 无法保证它在 NSPopover 的整个生命周期内都存在。为了使弹出窗口与 contactTableCellView 无关的生命周期存在,我的 class 中存在一个 NSPopover object 持有 NSTableView(我们称之为 addressBookViewController)。所以 addressBookViewController 将有一个名为 contactPopover 的成员,只要 addressBookViewController 仍在内存中,我们就可以确定 popover 将存在。这样做的问题是让 popover 的正确边界到 link 到。
如果您将当前的 contactTableCellView 传递回 addressBookViewController 并像@KenThomases 提到的那样使用 contactPopover.show(relativeTo:contactTableCellView.bounds of:contactTableCellView preferredEdge:.minY)
之类的东西,您会看到弹出窗口卡在 first/top 元素中NSTableView 无论我将鼠标悬停在哪个元素上,但我希望弹出窗口指向悬停在其上的元素。
我找不到任何参考资料 material 来证明我的假设,但从我的结果来看,NSTableView 似乎有 cells/views 包含我创建的自定义 ContactTableCellView。这就是我得到 "contactTableCellView.frame always has the (x,y) = (0,0)" 的原因。框架总是相对于 parent object,在本例中是与 TableCellView 具有相同大小的 view/cell。而这个外景有我wanted/expectedcontactTableCellView.frame有的框架。说清楚:
contactTableCellView.superView?.frame 在 NSTableView 中给出了正确的 (x,y),并且由于各种原因重绘了 contactTableCellView,因此该框架未被删除。使用我的发现,我能够让弹出窗口相对于正确的元素出现,就像我在 Swift 3:
中大致想要的那样
class AddressBookViewController {
...
var contactCardPopover: NSPopover?
...
func showContact(sender: AnyObject, contact: ContactVM) {
guard let contactTableCellView = sender as? ContactTableCellView else { return }
// when contactCardVC is non-nil, a popover currently open. This makes sure 2 don't open in the same tableView.
if contactViewController == nil {
contactCardViewController = ContactViewController(contact: contact)
// this here is the important part!!!! Using the contactTableCellView.superview
if let tableCell = participantTableCellView.superview {
contactCardPopover = NSPopover(contentViewController: contactCardViewController, sender: tableCell, bounds: tableCell.frame)
contactCardPopover.delegate = self
}
}
}
}
所以 ContactTableCellView 的超级视图具有正确的框架,所以我的 NSPopover 可以像我最初想要的那样在自定义 NSTableCellView 上工作!弄清楚这个特定部分只花了几个小时。
我正在尝试将 NSPopover 添加到 NSTableView 中的自定义 NSTableCellView。我能够让 NSPopover 出现对应于正确的元素,但弹出窗口的位置不正确。为了弄清楚我的问题,以防有人对设计提出更好的建议:当用户将鼠标悬停在 table 个联系人中的联系人上时,我想在弹出窗口中显示该联系人的更多信息(无需点击)
目前NSPopover初始化如下:
contactPopover = NSPopover(contentViewController: contactViewController, sender: allContactsViewController.view, bounds: contactTableCellView.frame)
该初始化程序只是轻轻地设置弹出行为并调用 popover.show(...)
其中 contactTableCellView 是我想要的联系人的 table 单元格视图。
问题是 contactTableCellView.frame
总是有 (x,y) = (0,0) 可能是因为这是自定义 NSTableCellView 的模板在 xib 中开始的地方。要将弹出窗口正确放置在 table 上,我需要获取 table 单元格视图相对于 NSTable 原点的位置。
现在每个 NSTableCellView 都有鼠标跟踪设置,所以在鼠标输入时,我通知联系人列表显示弹出框,我在其中传递相应的鼠标输入 table 单元格视图。这使我在尝试获取相对于 table 的位置时可以访问 table 单元格视图,但我在文档中找不到任何关于如何获取 [=] 的真实位置的信息25=] 相对于 table 原点的单元格视图。
看过:https://developer.apple.com/reference/appkit/nstableview https://developer.apple.com/reference/appkit/nstablecellview
我不确定这是关于什么的:
contactPopover = NSPopover(contentViewController: contactViewController, sender: allContactsViewController.view, bounds: contactTableCellView.frame)
那个方法是从哪里来的?它不是 NSPopover
本身的一部分。
无论如何,假设创建的弹出窗口没有多余的包袱,这应该可以满足您的需求:
contactPopover.show(relativeTo:contactTableCellView.bounds of:contactTableCellView preferredEdge:.minY)
这将使弹出窗口相对于单元格视图定位,而无需弄清楚单元格视图在 table 视图中的位置。
离开与@KenThomases 的会议,其中最好的方法是让 table 视图单元格本身管理弹出窗口,但这只是 half-possible。我来解释一下:
自从 table 重新绘制 table 单元格视图后,contactTableCellView 无法保证它在 NSPopover 的整个生命周期内都存在。为了使弹出窗口与 contactTableCellView 无关的生命周期存在,我的 class 中存在一个 NSPopover object 持有 NSTableView(我们称之为 addressBookViewController)。所以 addressBookViewController 将有一个名为 contactPopover 的成员,只要 addressBookViewController 仍在内存中,我们就可以确定 popover 将存在。这样做的问题是让 popover 的正确边界到 link 到。
如果您将当前的 contactTableCellView 传递回 addressBookViewController 并像@KenThomases 提到的那样使用 contactPopover.show(relativeTo:contactTableCellView.bounds of:contactTableCellView preferredEdge:.minY)
之类的东西,您会看到弹出窗口卡在 first/top 元素中NSTableView 无论我将鼠标悬停在哪个元素上,但我希望弹出窗口指向悬停在其上的元素。
我找不到任何参考资料 material 来证明我的假设,但从我的结果来看,NSTableView 似乎有 cells/views 包含我创建的自定义 ContactTableCellView。这就是我得到 "contactTableCellView.frame always has the (x,y) = (0,0)" 的原因。框架总是相对于 parent object,在本例中是与 TableCellView 具有相同大小的 view/cell。而这个外景有我wanted/expectedcontactTableCellView.frame有的框架。说清楚:
contactTableCellView.superView?.frame 在 NSTableView 中给出了正确的 (x,y),并且由于各种原因重绘了 contactTableCellView,因此该框架未被删除。使用我的发现,我能够让弹出窗口相对于正确的元素出现,就像我在 Swift 3:
中大致想要的那样class AddressBookViewController {
...
var contactCardPopover: NSPopover?
...
func showContact(sender: AnyObject, contact: ContactVM) {
guard let contactTableCellView = sender as? ContactTableCellView else { return }
// when contactCardVC is non-nil, a popover currently open. This makes sure 2 don't open in the same tableView.
if contactViewController == nil {
contactCardViewController = ContactViewController(contact: contact)
// this here is the important part!!!! Using the contactTableCellView.superview
if let tableCell = participantTableCellView.superview {
contactCardPopover = NSPopover(contentViewController: contactCardViewController, sender: tableCell, bounds: tableCell.frame)
contactCardPopover.delegate = self
}
}
}
}
所以 ContactTableCellView 的超级视图具有正确的框架,所以我的 NSPopover 可以像我最初想要的那样在自定义 NSTableCellView 上工作!弄清楚这个特定部分只花了几个小时。