【问题标题】:SwiftUI: Listening for changes in my data to have other views use the updated dataSwiftUI:监听我的数据中的变化,让其他视图使用更新的数据
【发布时间】:2023-03-09 07:25:02
【问题描述】:

我的主要视图是解码 JSON,然后枚举该 JSON 以显示城镇列表,您可以在其中切换 favorite 字段。
我想有一个单独的视图来只显示favorited 的城镇,我怀疑我想使用 ObservableObject 和@Published 来监听countries 的变化。我只是不知道如何实现这一点,因为我没有使用任何 class 对象。

Towns.json

[
    {
      "display_name": "California",
      "favorite": false,
    },
    {
      "display_name": "Colorado",
      "favorite": false,
    }

]

Town.swift

struct Town: Codable, Identifiable {
    var id: String {image}
    let display_name: String
    var favorite: Bool
}

MainView.swift

struct ContentView : View {

    @State var towns : [Town] = Bundle.main.decode("Towns.json")

    var body: some View {
        ForEach(Array(towns.enumerated()), id: \.1.id) { (index,town) in
            LazyVStack(spacing: 20) {
                HStack {
                    Text(town.display_name)
                    Spacer()
                    Button {
                        towns[index].favorite.toggle()
                    } label: {
                        if town.favorite {
                            Image(systemName: "flame").foregroundColor(.red)
                        } else {
                            Image(systemName: "flame.fill").foregroundColor(.red)
                        }
                    }
                }
            }
        }
    }
}

【问题讨论】:

    标签: swift swiftui swiftui-list


    【解决方案1】:

    是的,您可以使用 ObservableObject,但如果您只想在另一个视图中显示“最喜欢”的城镇,我会这样做:

    struct Town: Codable, Identifiable {
        var id: String = UUID().uuidString // for testing
        let display_name: String
        var favorite: Bool
    }
    
    struct ContentView: View {
        @State var showSecondView = false
        // @State var towns: [Town] = Bundle.main.decode("Towns.json")
        // for testing
        @State var towns: [Town] = [Town(display_name: "California", favorite: false),
                                   Town(display_name: "Colorado", favorite: false)]
    
        var body: some View {
            VStack {
                
                Button ("Show SecondView") { showSecondView.toggle() }
                
                ForEach(Array(towns.enumerated()), id: \.1.id) { (index,town) in
                    LazyVStack(spacing: 20) {
                        HStack {
                            Text(town.display_name)
                            Spacer()
                            Button {
                                towns[index].favorite.toggle()
                            } label: {
                                if town.favorite {
                                    Image(systemName: "flame").foregroundColor(.red)
                                } else {
                                    Image(systemName: "flame.fill").foregroundColor(.red)
                                }
                            }
                        }
                    }
                }
            }.sheet(isPresented: $showSecondView) {
                SecondTownView(towns: $towns)
            }
        }
    }
    
    struct SecondTownView: View {
        @Binding var towns: [Town]
        var body: some View {
            // here filter the towns on favorite
            ForEach(Array(towns.filter{$0.favorite}.enumerated()), id: \.1.id) { (index,town) in
                LazyVStack(spacing: 20) {
                    HStack {
                        Spacer()
                        Text(town.display_name)
                        Spacer()
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-16
      • 2023-03-27
      • 1970-01-01
      • 2012-05-26
      • 1970-01-01
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多