首页 > 解决方案 > NSTableView 的访问值

问题描述

我需要从另一个控制器访问基于单元格的 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"]

编辑 :

我尝试使用视图基础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 中...)

标签: swiftcocoanstableview

解决方案


首先,永远不要从视图(表视图)中获取数据,而是从模型(数据源数组)中获取数据。

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

  • 创建一个模型,必须继承一个类NSObject才能利用 Key-Value Coding

    @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 中首先选择表格视图(最简单的方法是⌃⇧-click进入表格视图区域并选择Table View),转到 Bindings Inspector(按⌥⌘7)并将Content绑定到View Controller并将Model Key Path设置为people

在此处输入图像描述

然后一一选择文本字段 - 再次⌃⇧-click在表格视图中的每个文本字段上并选择表格视图单元格- 并将绑定到Table Cell View并将模型键路径设置objectValue.<property>为例如

在此处输入图像描述

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

let secondFirstName = people[1].firstName

推荐阅读