所以我现在已经使用 Swift 大约 1 1/2 周了,并且来自 Objective-C,我认为以下内容会起作用。
我所做的一切都完全没有xib。
我有一堂课大致是这样的
class MyTableViewContainer : NSObject, NSTableViewDelegate, NSTableViewDataSource {
var selectedObjectInTable : AnyObject?
var dataTable : NSTableView()
var dataController : NSArrayController
func setUp() {
// everything else
tableView.bind(.content, to: dataController, withKeyPath: "arrangedObjects")
// everything else
}
func tableViewSelectionDidChange(_ notification: Notification) {
selectedObjectInTable = dataController.selectedObjects.first as AnyObject
}
}
另一个类
MyController
有一个 var myTableViewContainer : MyTableViewContainer
属性,并且它有一个 var textField : NSTextField
。
TableView 正确显示数据,就像我想要的那样。
假设表中的数据对象有一个属性
var name : String
。
我想做类似的事情
textField.bind(.value,
to: self.myTableViewContainer,
withKeyPath: "selectedObjectInTable." + "name"
)
但是什么也没发生。我的数据肯定没有 nil 名称,编译器不会抱怨...但我没有看到值绑定发生?
我做错了什么?
您想要将表格视图的
.content
、.selectionIndexes
和 .sortDescriptors
分别绑定到数组控制器的 arrangedObjects
、selectionIndexes
和 sortDescriptors
。
也许很明显,但我们还需要:
arrangedObjects
中的相应字段;和.contentArray
绑定到我们的模型对象。以下是使用
NSArrayController
将对象数组绑定到 macOS 中的表的示例:
import Foundation
class ViewController: NSViewController {
private let scrollView = NSScrollView()
private let tableView = NSTableView()
private let arrayController = NSArrayController()
private var observers: [NSKeyValueObservation] = []
// Your data source array
@objc dynamic var people: [Person] = [
Person(name: "John", age: 25),
Person(name: "Jane", age: 30),
Person(name: "Alice", age: 28)
]
override func viewDidLoad() {
super.viewDidLoad()
configure()
}
}
private extension ViewController {
func configure() {
configureTableView()
configureScrollView()
addObservers()
}
func configureTableView() {
tableView.translatesAutoresizingMaskIntoConstraints = false
let nameColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("NameColumn"))
nameColumn.title = "Name"
tableView.addTableColumn(nameColumn)
let ageColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("AgeColumn"))
ageColumn.title = "Age"
tableView.addTableColumn(ageColumn)
// Configure the NSArrayController
arrayController.bind(.contentArray, to: self, withKeyPath: "people", options: nil)
// Bind the table view to the array controller
tableView.bind(.content, to: arrayController, withKeyPath: "arrangedObjects", options: nil)
tableView.bind(.selectionIndexes, to: arrayController, withKeyPath: "selectionIndexes", options: nil)
tableView.bind(.sortDescriptors, to: arrayController, withKeyPath: "sortDescriptors", options: nil)
// Bind columns to the array controller
nameColumn.bind(.value, to: arrayController, withKeyPath: "arrangedObjects.name", options: nil)
ageColumn.bind(.value, to: arrayController, withKeyPath: "arrangedObjects.age", options: nil)
}
func configureScrollView() {
scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
// Set up constraints to ensure the table view fills the parent view
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
scrollView.documentView = tableView
scrollView.hasVerticalScroller = true
}
// for demonstration purposes, I'm just going to observe name changes
func addObservers() {
for person in people {
let observer = person.observe(\.name, options: [.old, .new]) { [weak self] _, change in
guard let self else { return }
print(people)
}
observers.append(observer)
}
}
}
class Person: NSObject {
@objc dynamic var name: String
@objc dynamic var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
extension Person {
override var description: String { "\(name) is \(age) years old" }
}