macOS SwiftUI 应用程序选项卡视图,工具栏中带有分段控件

NG2*_*235 10 macos xcode swift swiftui

我正在尝试使用 SwiftUI 创建一个 macOS 应用程序。我需要一个TabView或类似的东西,但是当我使用TabView分段控件时不在 macOS 工具栏中。单击此处查看我想要的示例

我目前的代码是:

import SwiftUI

struct ContentView: View {
    var body: some View {
        TabView {
            Text("1")
                .tabItem {
                    Text("1")
            }
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

结果在这里作为图像

分段控件需要在工具栏中而不是在视图中。

谢谢你。

Den*_*ise 5

当我想在 macOS BigSur 上构建类似的东西时,我偶然发现了你的问题。我正在使用Xcode 12.2

这是我的解决方案,灵感来自 Asperi 的答案。将窗口组的标题设置为空字符串“”很重要,否则看起来很奇怪。

请注意,它仅在运行应用程序时有效,在预览中无效!

标签栏示例

应用程序文件

import SwiftUI

@main
struct SegmentedToolbarApp: App {
    var body: some Scene {
        WindowGroup("") {
            ToolbarItemPlacement()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

工具栏项目放置视图

重要的部分是与校长的安置。

设置更大的 minWidth 也很重要 - 否则工具栏会消失!

import SwiftUI

struct ToolbarItemPlacement: View {
    
    private let tabs = ["Watch Now", "Movies", "TV Shows", "Kids", "Library"]
    @State private var selectedTab = 0
    
    var body: some View {
        VStack {
            ChildTabView(title: self.tabs[self.selectedTab], index: self.selectedTab)
        }
        .toolbar {
            ToolbarItem(placement: .principal) {
                
                Picker("", selection: $selectedTab) {
                    ForEach(tabs.indices) { i in
                        Text(self.tabs[i]).tag(i)
                    }
                }
                .pickerStyle(SegmentedPickerStyle())
                .padding(.top, 8)
            }
        }
        .frame(minWidth: 800, minHeight: 400)
    }
}
Run Code Online (Sandbox Code Playgroud)

子选项卡视图

struct ChildTabView: View {
    var title: String
    var index: Int

    var body: some View {
        Text("\(title) - Index \(index)")
            .padding()
    }
}
Run Code Online (Sandbox Code Playgroud)


Asp*_*eri 2

这是实现这一目标的可能方法的简化演示。已测试并适用于 Xcode 11.2。

演示

1)准备窗口,使其具有所需的样式和背景AppDelegate

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Create the SwiftUI view that provides the window contents.
    let contentView = ContentView()
        .edgesIgnoringSafeArea(.top)
        .frame(minWidth: 480, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)

    // Create the window and set the content view. 
    window = NSWindow(
        contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
        styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
        backing: .buffered, defer: false)
    window.center()
    window.titlebarAppearsTransparent = true
    window.titleVisibility = .hidden

    window.setFrameAutosaveName("Main Window")
    window.contentView = NSHostingView(rootView: contentView)
    window.makeKeyAndOrderFront(nil)
}
Run Code Online (Sandbox Code Playgroud)

2)准备窗口内容视图以具有所需的行为

func applicationDidFinishLaunching(_ aNotification: Notification) {
    // Create the SwiftUI view that provides the window contents.
    let contentView = ContentView()
        .edgesIgnoringSafeArea(.top)
        .frame(minWidth: 480, maxWidth: .infinity, minHeight: 300, maxHeight: .infinity)

    // Create the window and set the content view. 
    window = NSWindow(
        contentRect: NSRect(x: 0, y: 0, width: 480, height: 300),
        styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
        backing: .buffered, defer: false)
    window.center()
    window.titlebarAppearsTransparent = true
    window.titleVisibility = .hidden

    window.setFrameAutosaveName("Main Window")
    window.contentView = NSHostingView(rootView: contentView)
    window.makeKeyAndOrderFront(nil)
}
Run Code Online (Sandbox Code Playgroud)