How can I pin an NSPopover to a selected NSTableCellView in swift5

261 Views Asked by At

I have the code shown below, that pins an NSPopover to my NSTableView. I've looked all over Google, and SO, but I cannot find a way to pin the popover to a specific (selected) cell.

@objc func tableViewDoubleAction(sender: NSTableCellView) {

let message = "Please Choose"
let controller = NSViewController()
controller.view = NSView(frame: CGRect(x: CGFloat(100), y: CGFloat(50), width: CGFloat(300), height: CGFloat(250)))

let popover = NSPopover()
popover.contentViewController = controller
popover.contentSize = controller.view.frame.size

popover.behavior = .transient
popover.animates = true


popover.show(relativeTo: sender.bounds, of: sender as NSView, preferredEdge: NSRectEdge.maxY)

Here's an image to demonstrate the issue:

 an image

1

There are 1 best solutions below

0
Willeke On BEST ANSWER

From the documentation of NSTableView.doubleAction:

The clickedRow and clickedColumn properties allow you to determine which row and column the double-click occurred in or if, rather than in a row, the double-click occurred in a column heading.

@objc func tableViewDoubleAction(sender: NSTableView) {
    let row = sender.clickedRow

From the documentation of clickedRow:

The index of the row the user clicked to trigger an action message. Returns –1 if the user clicked in an area of the table view not occupied by table rows.

    if row >= 0 {

NSTableView has a method rect(ofRow:):

Returns the rectangle containing the row at the specified index.

        let rowRect = sender.rect(ofRow: row)

Use this rect to position the popover

        popover.show(relativeTo: rowRect, of: sender, preferredEdge: NSRectEdge.maxY)

Put it all together:

@objc func tableViewDoubleAction(sender: NSTableView) {
    let row = sender.clickedRow
    if row >= 0 {
        // create the popover
        let rowRect = sender.rect(ofRow: row)
        popover.show(relativeTo: rowRect, of: sender, preferredEdge: NSRectEdge.maxY)
    }
}