如何更新通过编程创建的NSTableView中呈现的数据源。

huangapple go评论66阅读模式
英文:

How can I update the datasource presented in a programmatically created NSTableView

问题

我是新手使用Cocoa(和Swift),正在尝试理解(基于View的)NSTableView、NSTableViewDataSource、NSTableViewDelegate、Storyboards、Notifications等内容。我试图创建一个具有不同数量列(和行)的NSTableView。我的表头是[String],我的行是[[String]](尽管出于标识目的,也可以是[[String: String]])。有很多涵盖类似主题的教程和Stack Overflow问题,因此通过编程生成表格不是问题。然而,我无法弄清楚如何在用户编辑单元格后得到通知以将数据存储回我的[[String]]

请注意,我可能已经查看了Apple论坛、Stack Overflow和其他地方涵盖此主题的每个帖子。如果将此问题标记为重复,请告诉我您的链接的哪一部分我应该查看以及如何调整它以适应我的需求。

目前,我的代码基本上与这个Stack Overflow问题上Robert的答案差不多,只是添加了一些按钮:一个用于print()我的[[String]]数据源,另一个用于调用他的setContent()函数。我还在tableView(_:viewFor:row:)中添加了cell.textField?.isEditable = true以使单元格可编辑。

我找到了一些指向tableView(_:setObjectValue:for:row:)的答案,但似乎从不会被调用 - 我猜想是因为根据苹果的文档这是为基于Cell的NSTableView设计的,而不是基于View的NSTableView。该页面说:“在基于视图的表格中,请使用目标/操作来设置视图单元格中的每个项目。”,但没有详细说明如何实现这一点。

这个看起来非常接近,但它是用Obj-C编写的,我发现很难转化为Swift。

英文:

I am new to Cocoa (and Swift) and am trying to wrap my head around a (View based) NSTableView, NSTableViewDataSource, NSTableViewDelegate, Storyboards, Notifications, etc. I am trying to create an NSTableView with a varying amount of columns (and rows). My header is a [String], my rows are a [[String]] (though if it's simpler for identification purposes, it could also be an [[String: String]]). There's a lot of tutorials/SO questions out there covering similar topics, so generating the table programmatically has not been an issue. However, I cannot figure out how to get notified to store data back into my [[String]] once a user edits a cell.

Please realise that I have probably looked at every post covering this topic on the Apple forums, SO, and others. If marking this question as a duplicate, please tell me which part of your link I have to look at and how I can adapt it for my purposes.

Currently my code is pretty much Robert's answer on this SO question with a couple of buttons added: one to print() my [[String]] datasource, and another to call his setContent() function. I have also added cell.textField?.isEditable = true to tableView(_:viewFor:row:) to make the cells editable.

I have found some answers pointing to tableView(_:setObjectValue:for:row:), however that never seems to get called - I assume because as per Apple's docs that is meant for Cell based NSTableViews, not View based NSTableViews. That page says "In view-based tables, use target/action to set each item in the view cell.", but does not go into further detail on how to implement this.

This seems very close but it's in Obj-C and I find difficult to adapt for Swift.

答案1

得分: 1

我最终将tableView(_:viewFor:row:)函数更改为包括以下内容:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    let column = tableView.tableColumns.firstIndex(of: tableColumn!)!
    tableColumn?.headerCell.title = header[column];

    if let cell = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: self) as? NSTableCellView {
        cell.textField?.stringValue = list[row][column]
        cell.textField?.isEditable = true
        cell.textField?.target = self
        cell.textField?.action = #selector(self.onEditCell(_:))
        return cell
    }

    return nil
}

并添加了以下函数:

@IBAction func onEditCell(_ sender: Any) {
    let row: Int = tableView.row(for: sender as! NSView)
    let col: Int = tableView.column(for: sender as! NSView)
    let content: String = (sender as? NSTextField)?.stringValue ?? ""

    print("Col: \(col), row: \(row), value: \(content)")
}
英文:

I ended up changing the tableView(_:viewFor:row:) function to include cell.textField?.target = self and cell.textField?.action = #selector(self.onEditCell(_:)), like so:

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    let column = tableView.tableColumns.firstIndex(of: tableColumn!)!
    tableColumn?.headerCell.title = header[column];

    if let cell = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: self) as? NSTableCellView {
        cell.textField?.stringValue = list[row][column]
        cell.textField?.isEditable = true
        cell.textField?.target = self                           // <-- added
        cell.textField?.action = #selector(self.onEditCell(_:)) // <-- added
        return cell
    }

    return nil
}

and adding the function:

@IBAction func onEditCell(_ sender: Any) {
    let row: Int = tableView.row(for: sender as! NSView)
    let col: Int = tableView.column(for: sender as! NSView)
    let content: String = (sender as? NSTextField)?.stringValue ?? ""

    print("Col: \(col), row: \(row), value: \(content)")
}

huangapple
  • 本文由 发表于 2023年5月28日 04:03:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76348810.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定