您将如何创建要循环访问的视图数组,为每个视图创建导航 link?
How would you create an array of views to loop through, to create a navigation link to each one of the views?
我有 8 个视图用于在水平滚动组中用户点击图像并转到相应的视图。 我知道我可以手动执行此操作,但使用 ForEach 循环会节省大量代码,我已经对文本执行了类似的操作,如下所示,我尝试对视图数组执行此操作,但是导航的参数要求 link 使得很难引用视图本身 ,因为它会是这样。 [dogs_and_cats 但导航 link 希望它是 dogs_and_cats()]。然而,由于以下错误,这不起作用:类型 'Any' 在导航 link 行中没有成员 'init' 并且无法将类型 'Barcelona_Museum_of_Contemporary_Art.Type' 的值转换为预期的元素类型 'Any.Protocol' 为每个数组元素。如果您处在我的位置,如果可能的话,您将如何创建一个视图对象数组,并为每个导航循环遍历它们 link?
let museumNamesForLink = [Whitney_Museum_of_American_Art,
The_Andy_Warhol_Museum,
Museum_of_Modern_Art, Nakamura_Keith_Haring_Collection,
Tate_Modern,
The_Broad_Museum,
Museum_fu_r_Moderne_Kunst,
Barcelona_Museum_of_Contemporary_Art]
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .top, spacing: 0) {
ForEach(museumNames.indices) { index in
VStack {
NavigationLink(destination: museumNamesForLink[index]()) {
Image(museumNames[index])
.resizable()
.aspectRatio(contentMode: .fit)
}
Text(museumNames[index])
.bold()
.font(.callout)
.foregroundColor(.white)
.multilineTextAlignment(.center)
.padding(.leading)
}
}
}
}
我可能会用一个 enum
来表示不同的博物馆类型,然后用一个 @ViewBuilder
函数和一个 switch
语句来处理这个问题,它可以给你一个不同的 View
基于 enum
被喂给它。
struct ContentView: View {
enum MuseumTypes: CaseIterable {
case whitney, warhol, moma
var name : String {
switch self {
case .whitney:
return "Whitney Museum"
case .warhol:
return "Warhol Musuem"
case .moma:
return "Museum of Modern Art"
}
}
}
@ViewBuilder func museumViewForType(type: MuseumTypes) -> some View {
switch type {
case .whitney:
WhitneyView()
case .warhol:
WarholView()
case .moma:
MomaView()
}
}
var body: some View {
NavigationView {
VStack {
ForEach(MuseumTypes.allCases, id: \.self) { museum in
NavigationLink(destination: museumViewForType(type: museum)) {
Text(museum.name)
}
}
}
}
}
}
struct WhitneyView : View {
var body: some View {
Text("Whitney")
}
}
struct WarholView : View {
var body: some View {
Text("Warhol")
}
}
struct MomaView : View {
var body: some View {
Text("MOMA")
}
}
另一种方法是将所有视图存储在数组中,并用 AnyView()
将它们包装起来,以便它们是同类类型(参见 ),但我认为这不是那么干净或者像我上面详述的方法一样清楚)。另外,通过使用 enum
而不是数组,如果您忘记大小写,编译器会发出警告,并保证您不会遗漏任何内容,也不会超出数组索引的范围。
我有 8 个视图用于在水平滚动组中用户点击图像并转到相应的视图。 我知道我可以手动执行此操作,但使用 ForEach 循环会节省大量代码,我已经对文本执行了类似的操作,如下所示,我尝试对视图数组执行此操作,但是导航的参数要求 link 使得很难引用视图本身 ,因为它会是这样。 [dogs_and_cats 但导航 link 希望它是 dogs_and_cats()]。然而,由于以下错误,这不起作用:类型 'Any' 在导航 link 行中没有成员 'init' 并且无法将类型 'Barcelona_Museum_of_Contemporary_Art.Type' 的值转换为预期的元素类型 'Any.Protocol' 为每个数组元素。如果您处在我的位置,如果可能的话,您将如何创建一个视图对象数组,并为每个导航循环遍历它们 link?
let museumNamesForLink = [Whitney_Museum_of_American_Art,
The_Andy_Warhol_Museum,
Museum_of_Modern_Art, Nakamura_Keith_Haring_Collection,
Tate_Modern,
The_Broad_Museum,
Museum_fu_r_Moderne_Kunst,
Barcelona_Museum_of_Contemporary_Art]
ScrollView(.horizontal, showsIndicators: false) {
HStack(alignment: .top, spacing: 0) {
ForEach(museumNames.indices) { index in
VStack {
NavigationLink(destination: museumNamesForLink[index]()) {
Image(museumNames[index])
.resizable()
.aspectRatio(contentMode: .fit)
}
Text(museumNames[index])
.bold()
.font(.callout)
.foregroundColor(.white)
.multilineTextAlignment(.center)
.padding(.leading)
}
}
}
}
我可能会用一个 enum
来表示不同的博物馆类型,然后用一个 @ViewBuilder
函数和一个 switch
语句来处理这个问题,它可以给你一个不同的 View
基于 enum
被喂给它。
struct ContentView: View {
enum MuseumTypes: CaseIterable {
case whitney, warhol, moma
var name : String {
switch self {
case .whitney:
return "Whitney Museum"
case .warhol:
return "Warhol Musuem"
case .moma:
return "Museum of Modern Art"
}
}
}
@ViewBuilder func museumViewForType(type: MuseumTypes) -> some View {
switch type {
case .whitney:
WhitneyView()
case .warhol:
WarholView()
case .moma:
MomaView()
}
}
var body: some View {
NavigationView {
VStack {
ForEach(MuseumTypes.allCases, id: \.self) { museum in
NavigationLink(destination: museumViewForType(type: museum)) {
Text(museum.name)
}
}
}
}
}
}
struct WhitneyView : View {
var body: some View {
Text("Whitney")
}
}
struct WarholView : View {
var body: some View {
Text("Warhol")
}
}
struct MomaView : View {
var body: some View {
Text("MOMA")
}
}
另一种方法是将所有视图存储在数组中,并用 AnyView()
将它们包装起来,以便它们是同类类型(参见 enum
而不是数组,如果您忘记大小写,编译器会发出警告,并保证您不会遗漏任何内容,也不会超出数组索引的范围。