NSTableView Right Clicked Row Index

后端 未结 5 1281
太阳男子
太阳男子 2020-12-29 09:16

I\'m looking for a way to get right-clicked row index from NSTableView but I can\'t find any delegate methods or class attributes for it. Any suggestion is appr

相关标签:
5条回答
  • 2020-12-29 09:29

    Just select row on right-click by implementing menuForEvent: in NSTableView subclass:

    @implementation MyTableView
    
    - (NSMenu *)menuForEvent:(NSEvent *)theEvent
    {
        int row = [self rowAtPoint:[self convertPoint:theEvent.locationInWindow fromView:nil]];
        if (row == -1) 
            return nil;
        if (row != self.selectedRow)
            [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
        return self.menu;
    }
    
    @end
    
    0 讨论(0)
  • 2020-12-29 09:35

    if you dont need to open NSMenu but need to know "right click action with row number", i think most simple way is below. (Swift4 Code) Don't need any other connected Outer NSMenu class.

    class SomeViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {
      @IBOutlet weak var tableView: NSTableView!
      ...
    
      override func viewDidLoad() {
        ...
        tableView.action = #selector(some method()) // left single click action
        tableView.doubleAction = #selector(someMethod()) // left double click action
      }
    
      // right click action
      override func rightMouseDown(with theEvent: NSEvent) {
        let point = tableView.convert(theEvent.locationInWindow, from: nil)
        let row = tableView.row(at: point)
        print("right click")
        print(row)
      }
    
    0 讨论(0)
  • 2020-12-29 09:39

    While I haven't done this, I am pretty sure you can by overriding NSView's - (NSMenu*)menuForEvent:(NSEvent*)theEvent. The example in this link does a point conversion to determine the index.

    -(NSMenu*)menuForEvent:(NSEvent*)theEvent
    {
        NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
       int row = [self rowAtPoint:mousePoint];
       // Produce the menu here or perform an action like selection of the row.
    }
    
    0 讨论(0)
  • 2020-12-29 09:45

    Use the NSTableView method - (NSInteger)clickedRow to get the index of the last clicked row. The returned NSInteger will be the index of the right clicked row.

    You do not need to subclass NSTableView for this solution. clickedRow is also available on NSOutlineView.

    0 讨论(0)
  • 2020-12-29 09:48

    Updated Answer

    If you want to get clicked row index on menu opening, the answer is NSTableView.clickedRow. Anyway this property is available only in specific moments, and usually just -1.

    When is this index to be available? That's in NSMenuDelegate.menuWillOpen method. So you conform the delegate and implement the method on your class, and access the clickedRow property. It's done.

    final class FileNavigatorViewController: NSViewController, NSMenuDelegate {
        let ov = NSOutlineView() // Assumed you setup this properly.
        let ctxm = NSMenu()
        override func viewDidLoad() {
            super.viewDidLoad()
            ov.menu = ctxm
            ctxm.delegate = self
        }
        func menuWillOpen(_ menu: NSMenu) {
            print(outlineView.clickedRow)
        }
    }
    

    Clicked row index is available until you click an item in the menu. So this also works.

    final class FileNavigatorViewController: NSViewController {
        let ov = NSOutlineView() // Assumed you setup this properly.
        let ctxm = NSMenu()
        let item1 = NSMenuItem()
        override func viewDidLoad() {
            super.viewDidLoad()
            ov.menu = ctxm
            ov.addItem(item1)
            ov.target = self
            ov.action = #selector(onClickItem1(_:))
        }
        @objc
        func onClickItem1(_: NSObject?) {
            print(outlineView.clickedRow)
        }
    }
    

    I tested this on macOS Sierra (10.12.5).


    Old Answer

    Starting from OS X 10.11, Apple finally added a method to access clickedRow easily. Just subclass NSTableView and override this method and you'll get the clickedRow as far as I experienced.

    func willOpenMenu(menu: NSMenu, withEvent event: NSEvent)
    

    This needs subclassing, but anyway, the cleanest and simplest way to access clickedRow.

    Also, there's a pairing method.

    func didCloseMenu(menu: NSMenu, withEvent event: NSEvent?)
    
    0 讨论(0)
提交回复
热议问题