快速绑定表格视图中的选择

问题描述 投票:0回答:1

所以我现在已经使用 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 名称,编译器不会抱怨...但我没有看到值绑定发生?

我做错了什么?

swift nstableview cocoa-bindings nsarraycontroller
1个回答
0
投票

您想要将表格视图的

.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" }
}
© www.soinside.com 2019 - 2024. All rights reserved.