ios - @State var 未按预期在 LazyVGrid 中更新

标签 ios swift swiftui ios14

我无法理解为什么我的变量“selectedItem”在此代码的一部分中被更新,而另一部分却没有。我的目标是做到这一点,当您点击网格中的图像时,它会将选定的图像名称传递给 ImageDetailView(理想情况下我希望它是一个 Navigationlink,但一张纸对我来说更容易测试......一个一步一个脚印)。

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

但是随后打开的工作表是空白的,因为它仍在寻找“测试”...控制台显示一条消息“在 Assets 目录中找不到名为“测试”的图像...”

为什么sheet还在使用“test”的初始化值?而不是更新后的值?

结构 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

构造 ImageDetailView: View {

@State var selectedItem: String

var body: some View {
    
    ZStack {
        Color.black.edgesIgnoringSafeArea(.all)
       Image(selectedItem)

            .resizable()
            .aspectRatio(contentMode: .fit)
            .cornerRadius(10)
    
    }
}

最佳答案

Sheet 在使用 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)

关于ios - @State var 未按预期在 LazyVGrid 中更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66190082/

相关文章:

scrollview - SwiftUI ScrollView 内容框架和偏移量

swift - 在 macOS 上使用 swiftUI 实现 webkit(并创建网页预览)

javascript - JSON 数据未出现在 iOS 中的响应 header 中

ios - EXC_BAD_ACCESS 错误但没有触发僵尸

ios - NSPredicate用于从多对多关系中获取项目,但不包括特定的相关实体

ios - 使用swift 2在for循环语句中解析json数据

ios - SwiftUI - 如何防止工作表中的键盘推高我的主 UI

ios - 维护 Cocoapods Podspec 源的 HTTP 下载链接

ios - NSString 的 boundingRect 函数误导行为

ios - 有没有办法在另一个推送到达时提前停止推送通知声音?