如何在 SwiftUI 中从孙子视图更新图像后刷新主视图上的图像

问题描述 投票:0回答:2

我有三级结构视图,我不知道如何将图像更改从第三级传递到第一级。我对如何在我的 "iconValue" 属性中使用 @State 和 @Binding 感到困惑。最高级别视图上的图像仅在关闭并重新打开屏幕后才会更改。

最高级别的视图是“ExLibrisStyleView”。它包括从“ExLibrisCategoryRow”视图提供的图标集合的行类别。在视图顶部显示选定的图标。 “ExLibrisCategoryRow”是从“ExLibrisCategoryItem”调用的图像的组合。当我点击任何图像时,我想立即更改视图顶部的选定图标。然而,在主视图被关闭并重新打开后它会发生变化 再次。非常感谢向我展示导致重新打开视图后图像更新的错误在哪里。

我每个结构视图的代码是:

ExLibrisStyleView
查看

    import SwiftUI

    struct ExLibrisStyleView: View {
   
    
    @EnvironmentObject var exlibrisData: ExLibrisModelData
   
    @State var iconValue = UserDefaults.standard.string(forKey: "iconValue")
   
    var body: some View {
      
        NavigationView{
                     
                List {
                    
                    
                    VStack(alignment: .leading) {
                        Text("Selected Bookmark").font(.headline).padding(.bottom,15)
         
                            Image(iconValue ?? "exlibris-0")
                                .renderingMode(.original)
                                .resizable()
                                .frame(width: 130, height: 130)
                                .cornerRadius(5)
                                .shadow(color: Color(red:0, green:0, blue:0, opacity:0.25), radius: 8, x: 0, y: 0)
                        
                    }
                    .padding(.leading, 15)
                    .padding(.bottom,30)
                    .listStyle(.inset)
                    .listRowInsets(EdgeInsets())
                
                    ForEach(exlibrisData.categories.keys.sorted(), id: \.self) { key in
                        ExLibrisCategoryRow(categoryName: key, items: exlibrisData.categories[key]!,iconValue: iconValue ?? "exlibris-0")
                            
                    }
                    .listRowInsets(EdgeInsets())
                }
                .listStyle(.inset)
                .navigationTitle("Bookmark Collection")
            }
        }
}

ExLibrisCategoryRow
查看

    import SwiftUI
    struct ExLibrisCategoryRow: View {
    
    var categoryName: String
    var items: [ExLibris]
    @State var iconValue: String
    var body: some View {
              
        VStack(alignment: .leading) {
            Text(categoryName)
                .font(.headline)
                .padding(.leading, 15)
            
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(alignment: .top, spacing: 0) {
                    ForEach(items) { exlibris in
                        
                    label: do {
                        ExLibrisCategoryItem(exlibris: exlibris, iconValue: $iconValue)
                    }
                    }
                }
            }
            .frame(height: 200)
        }       
    }
}

ExLibrisCategoryItem
查看

    import SwiftUI

    struct ExLibrisCategoryItem: View {
    
    var exlibris: ExLibris
    
    @Binding var iconValue: String
    
    
    var body: some View {
        
        VStack(alignment: .leading) {
            
            Image(exlibris.imageName)
                .renderingMode(.original)
                .resizable()
                .frame(width: 130, height: 130)
                .cornerRadius(5)
                .onTapGesture {
         
                    print(iconValue)
                    UserDefaults.standard.set(exlibris.imageName, forKey: "iconValue")
                    
                    iconValue = UserDefaults.standard.string(forKey: "iconValue") ?? "exlibris-0"
                
                }            
        }
        .padding(.leading, 15)
    }
}
ios swiftui view binding state
2个回答
1
投票

依赖关系始终用

@Binding
表示。因此,如果您希望您的依赖关系传播给孩子,它必须是

  • @State
    仅在祖父母
  • @Binding
    父母和孩子
  • 作为绑定传递,而不仅仅是传递给父级和子级的值(即
    $iconValue

所以:

  • ExLibrisStyleView
    景色还可以
  • ExLibrisCategoryItem
    景色还可以
  • ExLibrisCategoryRow
    视图应该有
@Binding var iconValue: String

这会将其链接到父级。然后你将它传递给这个视图作为

ExLibrisCategoryRow(categoryName: key, items: exlibrisData.categories[key]!,iconValue: $iconValue)

这是基础知识。在这种情况下(当您有 3 个从属视图时),另一个选择是不重新定义它们的属性,而是在视图模型中定义它们,然后可以在视图之间传递它们。 这是对此的一个不错的解释


0
投票

花了几个小时如何解决问题或更改视图背后的逻辑后,我以不同的方式搜索了解决方案,并找到了一个名为 @AppStorage 的优雅包装器,可以使用 UserDefaults 更新任何视图。这正是我一直在寻找的。我在这篇文章中找到了它,其他链接解释了如何使用。

关于用户默认更改监听的讨论

如何使用@AppStorage包装器

© www.soinside.com 2019 - 2024. All rights reserved.