2

ツールバー スタイルの NSTabViewController の SwiftUI ラッパーを設計しています。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ます。最後に、の配列を に渡す必要があります。これは、次の問題を除いてすべてうまく機能します。labelimageNSViewControllerRepresentableNSTabViewItemNSTabViewController

設計上NSTabViewController、最初のタブのみが読み込まれます。NSHostingControllerこれは、最初のをレイアウトする最初の をロードしますView。これは、最初のタブの を呼び出しonPreferenceChangeて設定します。labelただし、残りのタブはロードされないため、label未設定のままです。

ラベルと画像を明示的に渡すように API を再設計でき、それが機能することはわかっていますが、Apple はどのようにそれらを実装していTabViewますか? の macOS 実装TabViewNSTabViewController.

回避策は、この質問のタイトルであるすべてのタブを強制的にロードすることだと思いますが、他のアイデアも受け入れます。

参照:

https://github.com/utmapp/UTM/blob/dev/Platform/macOS/ToolbarTabView.swift

https://github.com/utmapp/UTM/blob/dev/Platform/macOS/ToolbarTabViewController.swift

4

1 に答える 1

0

これが私が思いついた愚かな回避策です

public class UTMTabViewController: NSTabViewController {
    public override func viewDidAppear() {
        super.viewDidAppear()
        for i in self.tabViewItems.indices {
            self.selectedTabViewItemIndex = i
        }
        self.selectedTabViewItemIndex = 0
    }
}

基本的に、ビューが表示されたらすべてのタブを強制的にロードします。これよりも良い答えがあることを本当に願っていますが、念のためここに残します。

于 2020-07-12T17:28:00.480 に答える