How to trigger an action from a NSTableCellView in view based NSTableView when using bindings

雨燕双飞 提交于 2019-12-04 07:54:58

Although you are using bindings you can still set your controller as the delegate for your tableview in the interface builder.

I see that you already are able to access the table view from inside your cell. The next task must be simple, just set the table view delegate as the target for your button's action.

Thanks for your question, I also will be triggering an action from a button on a NSTableView. Your question helped to put me on the correct path.

First to address the your solution to finding which row number my NSTableView is on. I was able to find it without knowing the button, in my custom NSTableView I installed the following as a first attempt:

- (NSInteger)myRowNumber  
{  
    return [(NSTableView*)self.superview.superview rowForView:self];  
}

this works fine, however it is less than robust. It only works if you already know specifically how deep you are in the view hierarchy. A more robust and universal solution is:

- (NSInteger)myRowNumber  
{   
    NSTableView* tableView = nil;   
    NSView* mySuperview = self;   

    do   
    {   
        NSView* nextSuper = mySuperview.superview;   
        if (nextSuper == nil)   
        {   
            NSException *exception =   
                [NSException exceptionWithName:@"NSTableView not found."   
                    reason:[NSString stringWithFormat:@"%@ search went too deep.",   
                    NSStringFromSelector(_cmd)] userInfo:nil];   
            @throw exception;   
        }   

        if ([nextSuper isKindOfClass:[NSTableView class]])   
            tableView = (NSTableView*)nextSuper;   
        else   
            mySuperview = mySuperview.superview;   
    } while (tableView == nil);   

    return [tableView rowForView:self];   
}   

this not only works at the NSTableView level, but works with anything installed at any level above it, no matter how complex the view hierarchy.

As to the unanswered part of your question, I established an IBOutlet in my class and using interface builder tied if to my files owner (in my case my document class). Once I had a reference to the class I was sending my message to, and the row number, I call the function. In my case the call required that I pass the row number it originates from.

[self.myDoc doSomethingToRow:self.myRowNumber];   

I tested this and it works at various levels of the view hierarchy above NSTableView. And it functions without having to have the row selected first (which appears to be assumed in Apples documentation).

Regards, George Lawrence Storm, Maltby, Washington, USA

Use rowForView: and the responder chain

To respond to a control's action embedded within an NSTableCellView, the control should issue the action to the First Responder. Alternatively, File Owner is possible but this is more tightly coupled.

Use rowForView: within the action method to determine which row's control issued the action:

- (IBAction)revealInFinder:(id)sender {
    NSInteger row = [self.tableView rowForView:sender];
    ...
}

The action is implemented within any of the responder chain classes. Most likely, this will be your subclassed NSWindowController instance. The responder could also be the application delegate; assuming the delegate has a means to talk to the NSTableView.

See Apple's example TableViewPlayground: Using View-Based NSTableView and NSOutlineView to see this in action.

Suhas answer helped me.

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

    if let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "EDIT_CELL_VIEW"), owner: self) as? SymbolManagerCell  {                    
                if let editButton = cell.subviews[0] as? NSButton {
                    editButton.target = cell // this is required to trigger action
                }
                return cell
            }
    return nil
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!