SwiftUI 2 - 如何在macOS和iPadOS中防止列表顶部区域关闭

9
在SwiftUI 2的导航栏中,我有一个包含多个部分的列表。所有部分都有标题,但是我希望顶部部分永远不会关闭,并且元素永远不会被隐藏。这仅适用于第一个标题,并且我希望折叠指示符/折叠符号消失或隐藏。 在SwiftUI 2中是否可以实现这一点? 我希望在macOS和iPadOS上实现这一点。
@State var agendaViews: [String] = ["Agenda", "Client", "Next Client"]
@State var treatmentViews: [String] = ["Treatment", "Products", "Merchandising"]
@State var selectionAgenda: String?

var body: some View {
    NavigationView {
        VStack {
            List(selection: $selectionAgenda) {
                Section(header: ListHeader()) {    // <<<<<<< For this section no Close Icon and No way to close this section.
                    ForEach(agendaViews, id: \.self) { string in
                        NavigationLink(destination: DetailsView(test: string)) {
                            Text(string)
                        }
                    }
                }
                Section(header: ListHeader2(), footer: ListFooter2()) {
                    ForEach(treatmentViews, id: \.self) { string in
                        NavigationLink(destination: DetailsView2(test: string)) {
                            Text(string)
                        }
                    }
                }
            }.listStyle(SidebarListStyle())
    }
  }
}

struct ListHeader1: View {
  var body: some View {
      HStack {
        Image(systemName: "calendar")
        Text("Agenda")
      }
    }
  }
  struct ListHeader2: View {
  var body: some View {
     HStack {
        Image(systemName: "person.3")
        Text("Clienten")
     }
    }
   }

   struct ListFooter3: View {
     var body: some View {
       Text("===")
     }
   }

我希望我的问题很清楚。 一如既往,非常感谢你。
添加了一些图片以显示一个部分标题有关闭和打开按钮。

Open & Close


提供的代码快照中没有关闭按钮(部分不可折叠)。至少在使用Xcode 12 / iPadOS 14进行测试时是如此。您能提供真实可测试的代码吗? - Asperi
这是代码,打开和关闭部分的按钮是由iPadOS制作的。正如您所看到的,我可以打开和关闭这些部分。不确定您想要表达什么其他意思。 - iPadawan
我还是解决不了这个问题。使用的是XCode 12 b4版本。有人能帮忙吗? - iPadawan
如果您不介意所有部分都不可折叠,那么这里的答案解决了我的问题。https://dev59.com/zlIG5IYBdhLWcg3wjBIU - Michael Schinis
3个回答

8

使用可折叠视图修饰符(collapsible view modifier)来处理Section。您的第一个Section将变为:

Section(header: ListHeader()) {
    ForEach(agendaViews, id: \.self) { string in
        NavigationLink(destination: DetailsView(test: string)) {
            Text(string)
        }
    }
}
.collapsible(false)

1
感谢您的回复。我只是在回复自己。我确实收到了“'collapsible' 在 iOS 上不可用”的通知。这不应该是 iPadOS 吗?然后我有下一个问题。如何在 Xcode 12 中创建一个完全基于 iPadOS SDK 的 iPadOS 项目? - iPadawan
1
哎呀,是的,我以为这个在所有平台上都可以使用,但它只适用于macOS。目前为止,我认为还没有办法创建一个新的iPadOS专属项目。你只需要从iOS项目模板开始即可。 - mikepj
1
在iOS上,您可以将列表样式更改为InsetGroupedListStyle()(以完全禁用折叠),而在macOS上,您可以使用.collapsible(false)来针对特定部分进行设置。 - Daniel

2

这个折叠功能完全基于SwiftUI对列表的判断。

据我所知,这种情况发生在列表内部的节(section)中。

我一直在尝试解决这个问题,所以我做了一个小示例应用程序。

列表样式示例应用程序的截图

import SwiftUI
struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                List {
                    Section {
                        Text(".automatic")
                    }
                }
                .listStyle(.automatic)
                List {
                    Section {
                        Text(".sidebar")
                    }
                }
                .listStyle(.sidebar)
                List {
                    Section {
                        Text(".plain")
                    }
                }
                .listStyle(.plain)
                List {
                    Section {
                        Text(".grouped")
                    }
                }
                .listStyle(.grouped)
                List {
                    Section {
                        Text(".inset")
                    }
                }
                .listStyle(.inset)
                 List {
                     Section {
                         Text(".insetGrouped")
                     }
                 }
                .listStyle(.insetGrouped)
            }
            .navigationTitle("ListStyle Examples")
        }
    }
}

除了.automatic和.sidebar外,其他东西似乎都会去掉折叠箭头 :)


只有 .sidebar 对我起作用。因为我想要额外的顶部空间被移除(似乎用于动画和粘性标题)。但是,我不希望用户折叠部分。 - chitgoks
在Xcode 15 beta 2上,箭头不再显示。 - AnupamChugh

2

虽然不是“最好的”解决方案,但目前是我的问题的解决方案。如果有更好的解决方案,请指正。

我已经在代码中更改了以下内容:

var body: some View {
        VStack  {
            List(selection: $selectionAgenda) {
                ListHeader1()
                ForEach(agendaViews, id: \.self) { string in
                    NavigationLink(destination: DetailsView2(test: string)) {
                        Text(string)
                    }
                }
                Section(header: ListHeader2(), footer: ListFooter2()) {
                    ForEach(treatmentViews, id: \.self) { string in
                        NavigationLink(destination: DetailsView2(test: string)) {
                            Text(string)
                        }

                    }

                }
            }
            .listStyle(SidebarListStyle())
       }
   }


struct ListHeader1: View {
    var body: some View {
        HStack {
            Image(systemName: "calendar")
            Text("Agenda")
        }.font(.title2)
    }
}

struct ListHeader2: View {
    var body: some View {
        HStack {
            Image(systemName: "person.3")
            Text("Clienten")
        }.font(.title2)
    }
}

在文本中,我只删除了列表的第一部分,并用Header View替换它,iPad上看起来很好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接