如您所见,HStack非常冗余。 我想要一个包含图像和文本的某种类型的数组 但是我不知道如何将该数组放入列表中,更重要的是,我不知道如何识别单击了数组中的哪个元素并根据单击的内容打开了新视图
struct ContentView: View {
var body: some View {
ZStack {
NavigationView {
List {
// as you can see the HStack is very redundant.
// I want to have an array of some type that contains both the image and the text
// But I do not know how to put that array into the list, more importantly I do not know how to recognize which element in the array was clicked and open a new view based on what is clicked
HStack {
Image("someImage")
.resizable()
.frame(width: 50, height: 50, alignment: .leading)
.clipShape(Circle())
NavigationLink (destination: SomeView()) {
Text("SomeText").foregroundColor(.gray)
.bold()
}
}
HStack {
Image("Image2")
.resizable()
.clipShape(Circle())
.frame(width: 50, height: 50, alignment: .leading)
NavigationLink(destination: image2()) {
Text("text2").foregroundColor(.gray)
.bold()
}
}
HStack {
Image("image3")
.resizable()
.clipShape(Circle())
.frame(width: 50, height: 50, alignment: .leading)
NavigationLink(destination: view3()) {
Text("view3").foregroundColor(.gray)
.bold()
}
}
}.navigationBarTitle("list")
}
}
}
}
答案 0 :(得分:1)
您可以这样做:
public struct ImageTextView<Destination> : Hashable where Destination: View {
public static func == (lhs: ImageTextView<Destination>, rhs: ImageTextView<Destination>) -> Bool {
return lhs.uuid == rhs.uuid
}
public var hashValue: Int {
return uuid.hashValue
}
var uuid = UUID().uuidString
var image: Image
var text : String
var destination: Destination
init(image: Image, text: String, destination: Destination) {
self.image = image
self.text = text
self.destination = destination
}
}
struct SomeView: View {
var body: some View {
Text ("navigation target")
}
}
let rows = [
ImageTextView(image: Image("someImage"), text: "SomeText", destination: SomeView())
// ImageTextView(image: Image("image2"), text: "text2", destination: SomeView())
]
struct ContentView: View {
var body: some View {
ZStack {
NavigationView {
List {
// as you can see the HStack is very redundant.
// I want to have an array of some type that contains both the image and the text
// But I do not know how to put that array into the list, more importantly I do not know how to recognize which element in the array was clicked and open a new view based on what is clicked
ForEach (rows, id: \.self) { row in
HStack {
row.image
.resizable()
.frame(width: 50, height: 50, alignment: .leading)
.clipShape(Circle())
NavigationLink (destination: SomeView()) {
Text(row.text).foregroundColor(.gray)
.bold()
}
}
}
}.navigationBarTitle("list")
}
}
}
}
答案 1 :(得分:1)
您将需要3个不同的数组或一个模型,由于您的问题是关于数组的,因此我将使用第一种使用数组的方法进行演示。
import SwiftUI
struct ContentView: View {
let views: [AnyView] = [AnyView(SomeView()), AnyView(Image2()), AnyView(View3())]
var body: some View {
NavigationView {
List {
ForEach(0...2, id: \.self) { index in
NavigationLink (destination: self.views[index]) {
ListRowView(index: index)
}
}
}.navigationBarTitle("List")
}
}
}
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
struct ListRowView: View {
var index: Int
let imageNames: [String] = ["cart","star","book"]
let textList: [String] = ["SomeText","text2","view3"]
var body: some View {
HStack {
Image(systemName: self.imageNames[index])
.resizable()
.clipShape(Circle())
.frame(width: 50, height: 50, alignment: .leading)
Text(self.textList[index])
.foregroundColor(.gray)
.bold()
}
}
}
struct SomeView: View {
var body: some View {
Text("SomeView")
.foregroundColor(.gray)
.bold()
}
}
struct Image2: View {
var body: some View {
Text("Image2")
.foregroundColor(.gray)
.bold()
}
}
struct View3: View {
var body: some View {
Text("View3")
.foregroundColor(.gray)
.bold()
}
}
第一个数组表示您的目标视图,其类型为AnyView
,另外两个数组是常规的String
数组,分别表示图像名称和文本。我仅将systemName
图像用于演示,您可以使用资产中的图像名称。
我希望这是您要寻找的,如果答案对您有用,请接受它作为答案。也不要犹豫,发表评论!