微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 swiftUI 生命周期中为三列视图添加工具栏分隔符 带有 Toolbar 的工具栏带有 ToolbarItemPlacement 的工具栏

如何解决如何在 swiftUI 生命周期中为三列视图添加工具栏分隔符 带有 Toolbar 的工具栏带有 ToolbarItemPlacement 的工具栏

我正在寻找一种方法来实现像 Mail.app 这样的三列布局的工具栏。此外,Notes.app 使用几乎相同的工具栏,两个应用程序之间唯一重要的区别是 Notes.app 看起来像 WindowStyle一个 HiddenTitleBarWindowStyle 而 Mail.app 看起来像一个 {{1} }.

以下应该是正确的:

  1. 如果侧边栏折叠,则有一个列表和详细信息视图
  2. 将列表与详细视图分开的分隔线一直向上穿过工具栏。 (这可以通过 Default|TitleBarWindowStyle 实现)

    sidebar collapsed - fully divided view

  3. 如果标题太长而无法放入导航列表,则垂直分隔线将被破坏:列表仍像以前一样从详细信息视图中划分出来,但现在工具栏看起来像一个 HiddenTitleBarWindowStyle,只有工具栏中的一条类似 DefaultwindowStyle 的小线。

    sidebar collapsed - divider line

实现此设置需要Divider()WindowStyleWindowToolbarStyle 配置的哪个组合?

编辑

我注意到无法删除 Notes.app 显示分隔线。不过,我还没有在文档中找到对任何此类元素的引用。

Notes.app Customizable Toolbar

代码示例

我已将问题归结为一个主要包含工具栏内容的简单应用程序。在我的原始代码中,我使用了两个嵌套的 .toolbar,而在示例中我只使用了一个 NavigationView 和两个列表。但是,NavigationView 结果是相同的。

带有 Toolbar 的工具栏

DefaultwindowStyle

此示例将导致 import SwiftUI @main struct ToolbarTestApp: App { var body: some Scene { WindowGroup { ContentView(titleBarIsHidden: true) } .windowToolbarStyle(UnifiedWindowToolbarStyle()) .commands { SidebarCommands() } } } struct ContentView: View { @State var destination: String = "Toolbar Test" @State var detail: String = "" var body: some View { NavigationView { List { Button(action: {self.destination = "Item with the identifier: 1"},label: { Text("Item 1") }) .buttonStyle(DefaultButtonStyle()) Button(action: {self.destination = "Item 2"},label: { Text("Item 2") }) .buttonStyle(DefaultButtonStyle()) } .listStyle(SidebarListStyle()) List { NavigationLink( destination: DetailView(text: "\(destination) – \(detail)").onAppear{self.detail = "Detail 1"},label: { Text("\(destination) – Detail 1") }) NavigationLink( destination: DetailView(text: "\(destination) – \(detail)").onAppear{self.detail = "Detail 2"},label: { Text("\(destination) – Detail 2") }) } .listStyle(InsetListStyle()) Text("\(destination) – \(detail)") } .navigationTitle(destination) .navigationSubtitle(detail) .toolbar(id: "nav") { ToolbarItem(id: "plus",placement: ToolbarItemPlacement.principal,showsByDefault: true) { HStack { Button(action: {print("pressed")},label: { Image(systemName: "plus.circle") }) } } ToolbarItem(id: "spacer",placement: ToolbarItemPlacement.confirmationAction,showsByDefault: true) { HStack { Spacer() } } ToolbarItem(id: "sidebar.end",showsByDefault: true) { Button(action: {print("pressed")},label: { Image(systemName: "sidebar.right") }) } } } } 永远不会显示将整个 Toolbar 分成两部分的分隔线。此外,第一个 Toolbar 位于 ToolbarItem 的中心。我尝试了所有 Toolbar,但都没有导致项目移动到与标题相邻的最左侧。

Default Window Style

带有 ToolbarItemPlacement 的工具栏

HiddenTitleBarWindowStyle

此示例将导致 @main struct ToolbarTestApp: App { var body: some Scene { WindowGroup { ContentViewForHiddenTitleBar() } .windowStyle(HiddenTitleBarWindowStyle()) // added hidden title style .windowToolbarStyle(UnifiedWindowToolbarStyle()) .commands { SidebarCommands() } } } struct ContentViewForHiddenTitleBar: View { @State var destination: String = "Toolbar Test" @State var detail: String = "" var body: some View { NavigationView { List { Button(action: {self.destination = "Item with the identifier: 1"},label: { Text("Item 2") }) .buttonStyle(DefaultButtonStyle()) } .listStyle(SidebarListStyle()) // add geometry reader to trim title width in toolbar GeometryReader { geometry in List { NavigationLink( destination: DetailView(text: "\(destination) – \(detail)").onAppear{self.detail = "Detail 1"},label: { Text("\(destination) – Detail 1") }) NavigationLink( destination: DetailView(text: "\(destination) – \(detail)").onAppear{self.detail = "Detail 2"},label: { Text("\(destination) – Detail 2") }) } // there is no title anymore so let's fake it. .toolbar(id: "list navigation") { ToolbarItem(id: "title",placement: ToolbarItemPlacement.navigation,showsByDefault: true) { vstack(alignment: .leading) { Text(destination) .font(.headline) .frame(maxWidth: .infinity,alignment: .leading) Text(detail) .font(.subheadline) .opacity(0.6) .frame(maxWidth: .infinity,alignment: .leading) } .frame(width: geometry.size.width) } } } .listStyle(InsetListStyle()) Text("\(destination) – \(detail)") } .navigationTitle(destination) .navigationSubtitle(detail) .toolbar(id: "nav") { // primary action will place the item next to the divider line. ToolbarItem(id: "plus",placement: ToolbarItemPlacement.primaryAction,label: { Image(systemName: "sidebar.right") }) } } } } 始终显示全高分隔线。即使标题太长。因此添加Toolbar。这很好,直到侧边栏崩溃。 GeometryReader 的位置将不正确。此外,在自定义 toolbaritems 时,可能会删除标题,但这是不可能的。

Hidden Title Bar Window Style

Hidden Title Bar Window Style with Collapsed Sidebar

解决方法

默认标题栏样式很好,您只需要将工具栏项附加到顶部 NavigationView 的子视图,例如:

var body: some View {
    NavigationView {
        
        List {
            ...
        }
        .listStyle(SidebarListStyle())
        .toolbar {
            ToolbarItem {
                Button(action: { },label: {
                    Image(systemName: "sidebar.right")
                })
            }
        }
        
        List {
            ...
        }
        .listStyle(InsetListStyle())
        .toolbar {
            ToolbarItem {
                Button(action: { },label: {
                    Image(systemName: "plus.circle")
                })
            }
        }
        
        Text("\(destination) – \(detail)")
    }
    .navigationTitle(destination)
    .navigationSubtitle(detail)
}

我没有将任何工具栏项附加到第三列(Text),但是您可以——只要确保将相同的工具栏项附加到您的 DetailViews,因为当用户导航。 (如果你不确定我的意思,试试看,你很快就会明白我在说什么:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?