【问题标题】:Access value of NSTableViewNSTableView 的访问值
【发布时间】:2025-11-24 21:20:03
【问题描述】:

我需要从另一个控制器访问基于单元格的 TableView 的值。我在主控制器中执行此代码,而 tableView 在子控制器中。
这是我所做的,但我得到了零……

// First grab the tableView controller
let myTableViewController = self.children[0] as! MyTableViewController

// Now I want to access the first row to get values of the textFields
let firstRowView = myTableViewController.theTable.rowView(atRow: 0, makeIfNecessary: true)

//Let's try another way :
let firstView = myTableViewController.theTable.view(atColumn: 0, row: 0, makeIfNecessary: true)

//I can't do more because "firstRowView" and "firstView " are nil

我想要的是一个包含表的所有字符串的数组,例如:

let array1 = ["Peter","Quinn","1","387","49"]

编辑:

我尝试使用 view base tableView,它可以工作,我可以在我的数组中获取 textFields。
但是,如果通过单击它来编辑文本字段(将“Peter”更改为“Franck”),它不起作用,NSTextField 在调试实用程序中消失......

let firstRowView = myTableViewController.theTable.rowView(atRow: 0, makeIfNecessary: true)?.subviews // return the first TableView
let textFields = firstRowView!.map { $0.subviews } as! [[NSTextField]]
let texts = textFields.map {$0.first!.stringValue}

print(texts) // let array1 = ["Peter","Quinn","1","387","49"]

如果我手动更改文本,为什么我不再工作了?

当我不手动编辑单元格时,“firstRowView”包含以下内容:

当我手动编辑单元格并崩溃时,“firstRowView”包含以下内容:

你可以看到 NSTableCellView 被转换成 NSView 并且我的 textField 已经消失了……(当然它还在 UI 中……)

【问题讨论】:

  • 不能从数据源获取数据吗?
  • 数据暂时设置在storyboard中,我可以(而且我需要)通过键盘编辑单元格来直接编辑数据。
  • 您是否打算在未来使用数据源或 Cocoa 绑定?

标签: swift cocoa nstableview


【解决方案1】:

首先不要从view(表格视图)获取数据,从model(数据源数组)获取数据。

在 macOS 中有一个非常方便的方法。使用 Cocoa Bindings 和基于 view 的表格视图。除了模型,几乎不需要任何代码。

  • 创建一个模型,继承自NSObject 的类是利用键值编码的必要条件

    @objcMembers
    class Person : NSObject {
        dynamic var firstName, lastName : String
        dynamic var age : Int
        dynamic var number1, number2 : Int
    
        init(firstName : String, lastName : String, age : Int, number1 : Int, number2 : Int) {
            self.firstName = firstName
            self.lastName = lastName
            self.age = age
            self.number1 = number1
            self.number2 = number2
        }
    }
    
  • 声明一个数据源数组

    @objc dynamic var people = [Person]()
    
  • 并填充它

    override func viewDidLoad() {
        super.viewDidLoad()
        people = [Person(firstName: "Peter", lastName: "Quinn", age: 1, number1: 387, number2: 49),
                  Person(firstName: "Peter", lastName: "Quinn", age: 1, number1: 387, number2: 49)]
    }
    

这就是全部代码。现在进行绑定。

在Interface Builder中首先选择表格视图(最简单的方法是⌃⇧-单击进入表格视图区域并选择表格视图),转到 Bindings Inspector(按 ⌥⌘7)并将 Content 绑定到 View Controller 并将 Model Key Path 设置为 @987654330 @。

然后一一选择文本字段——再次⌃⇧-单击表格视图中的每个文本字段并选择表格视图单元格 – 例如将 Value 绑定到 Table Cell View 并将 Model Key Path 设置为 objectValue.<property>

就是这样。表视图中的所有更改(例如编辑字段)都与模型同步。如果您想获得第二个条目的名字,只需编写

let secondFirstName = people[1].firstName

【讨论】:

  • 谢谢,我没用过cocoa装订,不过好像很好用。