Как настроить содержимое элемента таблицы при выборе и изменении акцента для NSTableView?
В настоящее время я пытаюсь создать трехпанельный макет в SwiftUI. Поскольку список SwiftUI не обеспечивает большей настройки, я решил создать свой собственный NSViewReprentable View на основе NSTableView. Я использую SwiftUI для элементов tableview. Вот частичный снимок экрана, на котором показано, как это выглядит с одним выбранным элементом:
У меня два вопроса:
- Когда элемент выбран, текст должен быть белого цвета. Как мне это сделать?
- Я до сих пор не знаю, как обеспечить применение правильного цвета (черный текст), если представление таблицы теряет фокус, например, при нажатии панели поиска (см. Снимок экрана ниже). Как я могу в этом убедиться?
Вот код, который я написал до сих пор:
struct MkList<Data, RowContent> : NSViewRepresentable where Data : RandomAccessCollection, RowContent : View {
var data: Data
var rowContent: (Data.Element) -> RowContent
public init(_ data: Data, @ViewBuilder rowContent: @escaping (Data.Element) -> RowContent) {
self.data = data
self.rowContent = rowContent
}
final class Coordinator: NSObject, NSTableViewDelegate, NSTableViewDataSource {
var parent: MkList<Data, RowContent>
init(_ parent: MkList<Data, RowContent>) {
self.parent = parent
}
func numberOfRows(in tableView: NSTableView) -> Int {
return parent.data.count
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
// Takes a SwiftUI view DownloadListItem(
let x = NSHostingView(rootView: parent.rowContent(parent.data[parent.data.index(parent.data.startIndex, offsetBy: row)]))
return x
}
func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
50
}
func tableViewSelectionDidChange(_ notification: Notification) {
let table = notification.object as! NSTableView
print(table.selectedRowIndexes.map({ $0 }));
}
}
func makeNSView(context: Context) -> NSScrollView {
let tableView = NSTableView()
tableView.delegate = context.coordinator
tableView.dataSource = context.coordinator
tableView.allowsMultipleSelection = true
tableView.headerView = nil
tableView.selectionHighlightStyle = .regular
tableView.gridStyleMask = NSTableView.GridLineStyle.solidHorizontalGridLineMask
let col = NSTableColumn()
col.minWidth = 250
tableView.addTableColumn(col)
let scrollView = NSScrollView()
scrollView.documentView = tableView
scrollView.hasVerticalScroller = true
scrollView.autohidesScrollers = true
return scrollView
}
func updateNSView(_ nsView: NSScrollView, context: Context) {
print("Update table called")
let tableView = (nsView.documentView as! NSTableView)
context.coordinator.parent = self
print(data)
// actually, model should tell us if reload is needed or not
tableView.reloadData()
// ... some basic logic to keep selection state ...
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
}
В
MkList
View используется следующим образом:
struct DownloadsView: View {
// The downloads will be retrieved and updated here only
@State var downloadsList: [String] = ["Download 1", "Download 2", "Download 3"]
var body: some View {
MkList(downloadsList) { i in
DownloadListItemView(downloadName: i)
}
}
}
В целом, как лучше всего решить эту проблему?