Reputation: 964
I'm trying to implement an NSTableView in a SwiftUI app in MacOS using NSViewRepresentable. The part of creating the table view works well so far:
struct TableView: NSViewRepresentable {
typealias NSViewType = NSTableView
func makeNSView(context: Context) -> NSTableView {
let tableView = NSTableView(frame: .zero)
tableView.delegate = context.coordinator
tableView.dataSource = context.coordinator
tableView.rowHeight = 20.0
tableView.gridStyleMask = [.solidVerticalGridLineMask, .solidHorizontalGridLineMask]
let nameColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "Name"))
nameColumn.title = "Name"
tableView.addTableColumn(nameColumn)
let ageColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "Age"))
ageColumn.title = "Age"
tableView.addTableColumn(ageColumn)
return tableView
}
func updateNSView(_ nsView: NSTableView, context: Context) {
nsView.reloadData()
}
func makeCoordinator() -> Coordinator {
return Coordinator()
}
}
extension TableView {
final class Coordinator: NSObject, NSTableViewDelegate, NSTableViewDataSource {
func numberOfRows(in tableView: NSTableView) -> Int {
return 12
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
switch tableColumn?.identifier.rawValue {
case "Name":
return "Person \(row)"
case "Age":
return "\(25 + row)"
default:
return nil
}
}
func tableView(_ tableView: NSTableView, shouldEdit tableColumn: NSTableColumn?, row: Int) -> Bool {
return true
}
func tableView(_ tableView: NSTableView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, row: Int) {
}
}
}
Of course, this only gives me the pure table, without a NSScrollView or a NSHeaderView.
My question is now: which would be the most elegant and SwiftUI-ish way to integrate NSScrollView and NSHeaderView?
Thanks!
Upvotes: 2
Views: 677
Reputation: 789
Thanks for you question, I used your code as base for my solution. Basically to show the NSTable header you need to wrap the NSTableView in a ScrollView. This is my final code
struct TableView: NSViewRepresentable {
typealias NSViewType = NSScrollView
func makeNSView(context: Context) -> NSScrollView {
let tableContainer = NSScrollView(frame: .zero)
let tableView = NSTableView(frame: .zero)
tableView.delegate = context.coordinator
tableView.dataSource = context.coordinator
tableView.rowHeight = 20.0
tableView.gridStyleMask = [.solidVerticalGridLineMask, .solidHorizontalGridLineMask]
let nameColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "Name"))
nameColumn.title = "Name"
tableView.addTableColumn(nameColumn)
let ageColumn = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: "Age"))
ageColumn.title = "Age"
tableView.addTableColumn(ageColumn)
tableContainer.documentView = tableView
tableContainer.hasVerticalScroller = true
return tableContainer
}
func updateNSView(_ nsView: NSScrollView, context: Context) {
guard let tableView = nsView.documentView as? NSTableView else { return }
tableView.reloadData()
}
func makeCoordinator() -> Coordinator {
return Coordinator()
}
}
Upvotes: 2