@State变量在LazyVGrid中未按预期更新



我很难理解为什么我的变量" selecteitem& quot;正在更新代码的一部分,而不是另一部分。我的目标是,当你点击网格中的图像时,它将选定的图像名称传递给ImageDetailView(理想情况下,我希望它是一个Navigationlink,但一个表格对我来说更容易测试)。一步一步来)。

在我有print(selectedItem)的地方,它按预期在控制台中打印LazyVGrid的tapped Image的名称。太棒了。

但是随后打开的工作表是空白的,因为它正在寻找"test"仍然……控制台显示一条消息:"在资产目录中找不到名为'test'的图像…">

为什么表格仍然使用"test的初始值?"而不是更新后的值?

struct ImagesView: View {

@State var gridLayout: [GridItem] = [ GridItem() ]
var title: String
var imageSet = [Photo]()
@State private var selectedItem = "test"
var body: some View {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
GeometryReader {  reader in
ScrollView {
LazyVGrid(columns: gridLayout, alignment: .center, spacing: 10) {
ForEach(imageSet.indices) { index in
Image(imageSet[index].name)
.resizable()
.onTapGesture {
showImageDetailView = true
selectedItem = imageSet[index].name
print(selectedItem)                                  
}                              
)}
.padding(.horizontal, 10)
.padding(.bottom, 25)

}
.sheet(isPresented: $showImageDetailView, content: {
ImageDetailView(selectedItem: selectedItem)
})

ImageDetailView

struct ImageDetailView: View {

@State var selectedItem: String
var body: some View {

ZStack {
Color.black.edgesIgnoringSafeArea(.all)
Image(selectedItem)
.resizable()
.aspectRatio(contentMode: .fit)
.cornerRadius(10)

}
}

}

表单对何时使用isPresented加载其内容很挑剔。

一个更可靠的解决方案是使用sheet(item: ),这将与您的情况下,只是一个小的修改selectedItem -它必须符合Identifiable。所以,你可以像这样包装它:

struct ImageSelection : Identifiable {
var name : String
var id: String {
return name
}
}

那么,selectedItem将成为可选的,因为它将决定工作表是否打开。下面是一个最小的示例,展示了可选选项以及如何在sheet(item:)中使用它:

struct ContentView : View {
@State var selectedItem : ImageSelection?

var body: some View {
Text("Test")
.sheet(item: $selectedItem) { item in
Text(item.name)
}
}
}

(注意,item被传递到工作表的闭包中——这是确保使用正确数据的方式)

根据你的评论:

selectedItem = ImageSelection(name: imageSet[index].name)
print(selectedItem?.name)

最新更新