如何在使用绑定时从基于NSTableView的NSTableCellView中触发操作

问题描述 投票:5回答:4

我在10.8上运行基于视图的NSTableView时遇到问题(目标是10.7,但我认为这不相关)。

我正在使用NSTableView,我通过绑定获取自定义NSTableCellView的内容值。我使用NSTableCellView的obejctValue来获取我的数据。

我在单元格中添加了一个按钮,我希望它在单击时触发一些动作。到目前为止,我只能在自定义NSTableCellView的子类中触发一个动作。

我可以使用链获得这样点击的行:

NSButton *myButton = (NSButton*)sender;    

NSTableView *myView = (NSTableView*)myButton.superview.superview.superview;

NSInteger rowClicked = [myView rowForView:myButton.superview];

从那里我不知道如何到达定义了操作的App Delegate或控制器。

当我使用cocoa绑定时,我没有NSTableView上的委托,我可以使用它来触发我的操作。

你知道我怎么能和控制器交谈吗?

提前谢谢了!

nstableview cocoa-bindings nstablecellview
4个回答
3
投票

虽然您正在使用绑定,但仍可以将控制器设置为界面构建器中tableview的委托。

我看到您已经能够从单元格内部访问表格视图。下一个任务必须简单,只需将表视图委托设置为按钮操作的目标。


3
投票

感谢您的提问,我还将通过NSTableView上的按钮触发操作。你的问题有助于我走上正确的道路。

首先解决您的解决方案,找到我的NSTableView所在的行号。我能够在不知道按钮的情况下找到它,在我的自定义NSTableView中,我安装了以下内容作为第一次尝试:

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

这种方法很好,但它不够健壮。只有在您已经明确了解视图层次结构中的深度时,它才有效。更强大和通用的解决方案是:

- (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];   
}   

这不仅适用于NSTableView级别,而且适用于安装在其上方任何级别的任何内容,无论视图层次结构有多复杂。

至于你问题的未解答部分,我在我的班级中建立了一个IBOutlet,并使用接口构建器绑定到我的文件所有者(在我的情况下是我的文档类)。一旦我有了对我发送消息的类的引用,以及行号,我就调用了该函数。在我的情况下,调用要求我传递它来自的行号。

[self.myDoc doSomethingToRow:self.myRowNumber];   

我对此进行了测试,它可以在NSTableView上方的视图层次结构的各个级别上运行。它的功能无需首先选择行(这似乎在Apples文档中假设)。

此致,George Lawrence Storm,Maltby,华盛顿,美国


1
投票

Use rowForView: and the responder chain

为了响应嵌入在NSTableCellView中的控件的操作,控件应该向第一响应者发出操作。或者,文件所有者是可能的,但这是更紧密耦合。

在action方法中使用rowForView:来确定哪一行的控件发出了操作:

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

该操作在任何响应者链类中实现。最有可能的是,这将是你的子类NSWindowController实例。响应者也可以是申请代表;假设代表有办法与NSTableView交谈。

请参阅Apple的示例TableViewPlayground: Using View-Based NSTableView and NSOutlineView以了解此情况。


0
投票

Suhas回答帮助了我。

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
}
© www.soinside.com 2019 - 2024. All rights reserved.