Created
May 23, 2024 05:50
-
-
Save robertmryan/0255230890a86931d06a5ed439171dfb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
// Create and 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" } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment