Использование координатора SwiftUI с NSTableView в NSViewControllerRepresentable?

#macos #swiftui #nstableview #coordinator #nsviewcontrollerrepresentable

#macos #swiftui #nstableview #координатор #nsviewcontrollerrepresentable

Вопрос:

Я разработал приложение для личных финансов macOS в SwiftUI, которое использует NSTableViews и NSOutlineViews через NSViewControllerRepresentable интерфейс между SwiftUI и AppKit.

Я обнаружил, что возможности просмотра AppKit намного превосходят все, что я могу создать с помощью списков SwiftUI, плюс они работают быстрее и поддерживают выбор типов. Передача данных в Appkit ViewControllers проста, но получение информации кажется менее сложным.

Документация разработчика Apple предполагает, что я должен использовать Coordinator класс, и я пытался это сделать, но безрезультатно. Делегированный метод, который мне нужен ( func tableViewSelectionDidChange(_ notification: Notification) ), не запускается (изнутри моего Coordinator класса).

На данный момент я обмениваюсь данными и действиями NotificationCenter.default , и это работает хорошо, но я очень хочу использовать «официальный» метод. Я нашел приложение для macOS, которое успешно использует Coordinator (по адресу https://www.markusbodner.com/til/2021/02/08/multi-line-text-field-with-swiftui-on-macos /) но я не могу заставить свой Coordinator класс работать как a NSTableViewDelegate , даже если он строится и запускается без ошибок (Xcode 12.4).

Все, что я хочу сделать для начала, это получить NSViewController элемент, содержащий a NSTableView , чтобы передать NSTableView.selectedRow его в родительское представление SwiftUI через a Coordinator , всякий раз, когда пользователь выбирает новую строку в NSTableView. Кто-нибудь может помочь (с некоторым примером кода, если это возможно, пожалуйста)?

Ответ №1:

Кажется, я нашел решение своей собственной проблемы. Я выделял свой NSTableViewDelegate координатору в makeNSViewController функции. Однако, похоже, что экземпляр my NSTableView не создается до тех пор, пока не будет запущен код, который заполняет содержимое my NSTableView ( NSTableViewDataSource в updateNSViewController функции). В результате нет NSTableViewDelegate возможности выделить.

Переход tableVC.tableView?.delegate = context.coordinator в updateNSViewController функцию, следуя коду, который заполняет содержимое my NSTableViewDataSource , делает мою NSTableViewDelegate работу по назначению, и tableView.selectedRow значения теперь успешно передаются в мой родительский SwiftUI view func tableViewSelectionDidChange(_ notification: Notification) . Ура!

Может быть полезно отметить, что я использую привязки Cocoa в my NSTableView и обнаружил, что необходимо оставить пустые @IBAction func заглушки (перетаскиваемый с помощью ctrl конструктор интерфейса формы как обычно) в ViewController (владелец файла) и поместить копии этих функций (заполненных кодом, конечно) в мой Класс координатора, чтобы заставить их код выполняться по назначению.

Итоговый общий код намного аккуратнее, чем мой старый код, который использовал уведомления для передачи действий и данных между SwiftUI и AppKit, поэтому «официальный» метод выглядит наилучшим.

Комментарии:

1. Вот ссылка на исходный код: ссылка