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

有任何想法吗?我看到我可以在 Interface Builder 中设置隐藏的列,但是似乎没有一个好时机来浏览这些列并检查它们是否为空,因为似乎没有一种方法可以在填充表中的所有数据之前/之后调用。

有帮助吗?

解决方案

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

其他提示

在 Mac OS X v10.5 及更高版本中,有 setHidden: 选择器 对于 NSTableColumn。

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

NSInteger colIdx;
NSTableColumn* col;

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

我已经使用绑定完成了此操作,但以编程方式设置它们,而不是通过 Interface Builder。

这个伪片段应该告诉你它的要点:

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

当然,您也可以添加格式化程序和所有这些东西。

它在 Interface Builder 中不起作用。然而它以编程方式工作。以下是我如何将带有标识符“Status”的 NSTableViewColumn 绑定到 NSUserDefaults 中的键:

迅速:

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

Objective-C:

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

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

NSTableColumn 没有 Visibility 绑定,但您可以将宽度设置为 0。

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

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

不可能一次性填充所有数据。NSTableView 不存储数据,它动态地从其数据源(或绑定到对象,如果您使用绑定)请求数据。它只是使用从数据源获取的数据进行绘制,然后放弃它。例如,您不应该看到该表要求提供任何不可见的数据。

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

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

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

我想发布我的解决方案,使用 Cocoa 绑定和实际的 Swift 4 更新 isHidden 标记而不触及列宽(因为您可能需要随后恢复原始值......)。假设我们有一个复选框来切换某些列的可见性(或者您始终可以切换 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
     }
}

正如您可能已经注意到的,目前还没有办法绑定 Hidden Interface Builder 中的标记与 XCode10 相同:你可以看到 Enabled 或者 Editable 绑定,但只有以编程方式您才能访问 isHidden 列的标志,正如 Swift 中所称的那样。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top