动态隐藏NSTableView中的列

时间:2008-09-16 02:14:22

标签: cocoa macos

我想根据要显示的数据动态隐藏/显示NSTableView中的一些列 - 基本上,如果列为空,我希望隐藏该列。我目前正在使用控制器类作为表的委托来填充表。

有什么想法吗?我看到我可以在Interface Builder中设置隐藏的列,但是似乎没有时间通过​​列并检查它们是否为空,因为似乎没有一个方法是在填充表格中的所有数据之前/之后调用。

8 个答案:

答案 0 :(得分:12)

在Mac OS X v10.5及更高版本中,NSTableColumn有setHidden: selector

这允许使用标识符动态隐藏/显示列:

NSInteger colIdx;
NSTableColumn* col;

colIdx = [myTable columnWithIdentifier:@"columnIdent"];
col = [myTable.tableColumns objectAtIndex:colIdx];
[col setHidden:YES];

答案 1 :(得分:3)

我已经使用绑定完成了这项工作,但是以编程方式而不是通过Interface Builder进行设置。

这个psuedo-snippet应该给你一个要点:

NSTableColumn *aColumn = [[NSTableColumn alloc] initWithIdentifier:attr];
[aColumn setWidth:DEFAULTCOLWIDTH];
[aColumn setMinWidth:MINCOLWIDTH];
[[aColumn headerCell] setStringValue:columnLabel];

[aColumn bind:@"value"
     toObject:arrayController 
  withKeyPath:keyPath 
  options:nil];             

[tableView addTableColumn:aColumn];
[aColumn release];

当然,您也可以添加格式化程序和所有内容。

答案 2 :(得分:2)

它在Interface Builder中不起作用。但它以编程方式工作。以下是我如何使用标识符" Status"绑定NSTableViewColumn。到我的NSUserDefaults中的一个键:

<强>夫特:

tableView.tableColumnWithIdentifier("Status")?.bind("hidden", toObject: NSUserDefaults.standardUserDefaults(), withKeyPath: "TableColumnStatus", options: nil)

<强>目标-C:

[[self.tableView tableColumnWithIdentifier:@"Status"] bind:@"hidden" toObject:[NSUserDefaults standardUserDefaults] withKeyPath:@"TableColumnStatus" options:nil];

答案 3 :(得分:1)

我目前没有完整的答案,但请查看Bindings。通常可以使用Cocoa Bindings做各种各样的事情。

NSTableColumn没有可见性绑定,但您可以将宽度设置为0.

然后,您可以将其绑定到Null Placeholder,并将此值设置为0 - 但不要忘记将其他占位符设置为合理的值。

(正如我所说,这只是一个开始,可能需要一些调整)。

答案 4 :(得分:0)

没有一次填充所有数据。 NSTableView不存储数据,它会动态地从数据源(或绑定到对象,如果您正在使用绑定)请求数据。它只是使用从数据源获取的数据并将其丢弃。例如,您不应该看到该表要求提供任何不可见的数据。

听起来你正在使用数据源?当数据发生变化时,你有责任在表上调用-reloadData,这有点用词不当。它更像是“使一切无效”。

也就是说,您应该已经知道数据何时发生变化。这就是你可以计算隐藏哪些列的点。

答案 5 :(得分:0)

@amrox - 如果我正确理解你的建议,你说我应该将值绑定到表中NSTableColumns的hidden属性?这似乎可以工作,但我不认为NSTableColumn有隐藏属性,因为isHidden和setHidden消息控制列的可见性 - 这告诉我这不是属性,除非我遗漏了某些东西(这很可能)。

答案 6 :(得分:0)

NSTable就是绘制表格的类。正如你自己所说,你有一些类,你把表作为委托,这个类为表提供要显示的数据。如果将表数据存储为代理类中的NSArray,则应该很容易找出一列是否为空,不是吗?并且NSArray通过委托方法向您的班级询问有多少列,因此当您被问到时,为什么不查找您拥有数据的列数并报告该数字而不是您在内部存储的实际列数,然后在被要求时提供(列,行)的数据,只需跳过空列。

答案 7 :(得分:0)

我想发布我的解决方案,它使用Cocoa绑定和实际的isHidden标志针对Swift 4进行了更新,而没有触及列宽(因为之后可能需要恢复原始值...)。假设我们有一个复选框来切换某些列的可见性(或者您始终可以按照您喜欢的任何其他方式在下面的示例中切换hideColumnsFlag变量):

class ViewController: NSViewController {

     // define the boolean binding variable to hide the columns and use its name as keypath
     @objc dynamic var hideColumnsFlag = true

     // Referring the column(s)
     // Method 1: creating IBOutlet(s) for the column(s): just ctrl-drag each column here to add it
     @IBOutlet weak var hideableTableColumn: NSTableColumn!
     // add as many column outlets as you need...

     // or, if you prefer working with columns' string keypaths
     // Method 2: use just the table view IBOutlet and its column identifiers (you **must** anyway set the latter identifiers manually via IB for each column)
     @IBOutlet weak var theTableView: NSTableView! // this line could be actually removed if using the first method on this example, but in a real case, you will probably need it anyway.

     // MARK: View Controller Lifecycle

     override func viewDidLoad() {
         super.viewDidLoad()

         // Method 1
         // referring the columns by using the outlets as such:
         hideableTableColumn.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column outlet.

         // Method 2
         // or if you need/prefer to use the column identifiers strings then:
         // theTableView.tableColumn(withIdentifier: .init("columnName"))?.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column identifier you have set.

         // obviously use just one method by commenting/uncommenting one or the other.
     }

     // MARK: Actions

     // this is the checkBox action method, just toggling the boolean variable bound to the columns in the viewDidLoad method.
     @IBAction func hideColumnsCheckboxAction(_ sender: NSButton) {
         hideColumnsFlag = sender.state == .on
     }
}

您可能已经注意到,还没有办法像XCode10一样在Interface Builder中绑定Hidden标志:您可以看到EnabledEditable绑定,但只能通过编程方式进行您将可以访问列的isHidden标志(在Swift中会被调用)。

如注释中所述,第二种方法依赖于您必须在选择相关列之后通过“接口构建器”在“标识”字段上手动设置的列标识符,或者,如果您具有列名称数组,则可以枚举表列并分配标识符和绑定,而不是重复相似的代码行。