How to create table with highlighted-on-mouseover cells on macOS cocoa?

1.7k views Asked by At

I'm trying to create a tray popover app with table very similar to the one Dropbox has in it's popover view. There is a table of files and when you hover mouse over a table cell, cell will highlight and show additional controls. I'm not sure if NSTableView is suitable for this at all? Does anyone have any advice?

Dropbox Popover Table WIth Highlighted Cell

2

There are 2 answers

3
Lucas Derraugh On BEST ANSWER

This would be an ideal use of NSTableView. Using a view-based NSTableView, you'll be easily able to create the look of those cells (views). The highlight on mouse-over should be accomplishable if you add an NSTrackingArea to the table view (scroll view might be better) with -[NSView addTrackingArea:], which gives you callbacks for -mouseMoved: events. From that method you can use the locationInWindow property on the NSEvent, and then use NSTableView's -rowAtPoint: call to query which row you should change to display the hover event.

0
AJ Venturella On

As a possible amendment here, I had to do the following to make this work:

highlightedRow: MyCustomRow?

func viewWillAppear(){
    configureTableHighlight()
}

func configureTableHighlight() {
    let trackingArea = NSTrackingArea(rect: scrollView.frame, options: [.mouseMoved, .activeInKeyWindow, .inVisibleRect], owner: self, userInfo: nil)
    scrollView.addTrackingArea(trackingArea)
}

override func mouseMoved(with event: NSEvent) {
    let pointInTableView = tableView.convert(event.locationInWindow, to: nil)
    let row = tableView.row(at: pointInTableView)
    
    if row == -1 {
        highlightedRow?.highlight = false
        highlightedRow = nil
        return
    }
    
    guard let view = tableView.view(atColumn: 0, row: row, makeIfNecessary: false) as? MyCustomRow else {
        return
    }
    
    if(highlightedRow == view){
        return
    }
    
    view.highlight = true;
    highlightedRow?.highlight = false
    highlightedRow = view;
}

This might depend on where you add the trackingView however.

Additional reference:

mouseover detection in NSTableView's NSCell?