Я разрабатываю оболочку SwiftUI для NSTabViewController со стилем панели инструментов. Я хочу, чтобы он был заменой TabView. TabView использует модификатор tabItem(_:)
для указания имени вкладки и значка. Поэтому я разработал аналогичный модификатор для своего собственного ToolbarTabView
:
extension View {
func toolbarTabItem(_ label: LocalizedStringKey, nsImage: NSImage? = nil, tooltip: LocalizedStringKey? = nil) -> some View {
self.preference(key: ToolbarTabItemPreferenceKey.self, value: ToolbarTabItemPreference(label: label, nsImage: nsImage, tooltip: tooltip))
}
}
. Я оборачиваю каждый View
в NSHostingController
и создаю NSTabViewItem
. Затем я использую onPreferenceChange
, чтобы установить свойство NSTabViewItem
label
и image
. Наконец, у меня есть NSViewControllerRepresentable
, чтобы передать мой массив NSTabViewItem
в NSTabViewController
. Все это работает хорошо, за исключением следующей проблемы.
По замыслу NSTabViewController
загружает только свою первую вкладку. Это загружает первый NSHostingController
, который выкладывает первый View
. Это вызывает onPreferenceChange
и устанавливает label
для первой вкладки. Однако оставшиеся вкладки не загружены, и поэтому label
остается неустановленным.
Я знаю, что могу перепроектировать свои API для явной передачи меток и изображений, и это работает, но тогда как Apple реализовать свои TabView
? У них должна быть такая же проблема с ленивой загрузкой представлений, потому что реализация macOS TabView
выглядит как NSTabViewController
.
Я думаю, что обходным путем будет принудительная загрузка всех вкладок, что является заголовком этого вопроса, но я открыт и для других идей.
Ссылка:
https://github.com/utmapp/UTM/blob/dev/Platform/macOS/ToolbarTabView.swift
https://github.com/utmapp/UTM/blob/dev/Platform/macOS/ToolbarTabViewController.swift