【问题标题】:How do I use Observable Object and Binding with the NavigationLink in SwiftUI?如何在 SwiftUI 中使用可观察对象并与 NavigationLink 绑定?
【发布时间】:2021-03-21 09:18:41
【问题描述】:

我是 Swift 和 SwiftUI 的新手,我正在练习使用属性包装器。我创建了一个简单的应用程序,您可以在其中单击伦敦、纽约或迈阿密。一旦您点击其中任何一个,它将导航到它自己的屏幕,该屏幕将显示城市名称、当前时间和 covid 死亡人数。

我没有将它连接到我只是想练习的 API。我花了将近 8 个小时试图找到一种方法,让城市在第二个视图中显示自己的属性,而无需创建 3 个单独的视图模型。每个导航目的地显示伦敦的属性。我正在尝试找到一种方法来解决它。我还从可识别模型中创建了 3 个对象/实例。如果你能帮助我,非常感谢。

这是我的视图模型:

class CityViewModel: ObservableObject {


@Published var title = "London"
@Published var deaths = "5894"
@Published var time = "8:36"

}

现在这是我的内容视图:

struct ContentView: View {
@ObservedObject var cities = CityViewModel()


    
var body: some View {
    NavigationView {
        ZStack {
            Color.black
                .ignoresSafeArea()
        
        VStack {
            
            NavigationLink(
                destination: ToogleView(cityname: self.$cities.title, deaths: self.$cities.deaths, time: self.$cities.time),
                label: {
                    Text("London")
                        .foregroundColor(.white)
                        .bold()
                        .font(.system(size: 30))
                   
                })
            Spacer()
            NavigationLink(
                destination: ToogleView(cityname: self.$cities.title, deaths: self.$cities.deaths, time: self.$cities.time),
                label: {
                    Text("New York")
                        .foregroundColor(.white)
                        .bold()
                        .font(.system(size: 30))
                })

我为单击 Navigationlink 时创建了第二个视图

struct ToogleView: View {

@Binding var cityname:String
@Binding var deaths:String
@Binding var time:String




var body: some View {
    ZStack {
        Color.black
            .ignoresSafeArea()
        VStack {
            Spacer()
            Text(cityname)
                .foregroundColor(.white)
                .font(.system(size: 24))
                .bold()
            Spacer()
            Text(time)
                .foregroundColor(.white)
                .font(.system(size: 18))
            Spacer()
            HStack{
                Image(systemName: "person.3.fill")
                    .foregroundColor(.white)
                Text(deaths)
                    .foregroundColor(.red)
                    .bold()
                
                
                    
                    
            }
        Spacer()
        }
    }
  }
}

【问题讨论】:

    标签: swift xcode swiftui


    【解决方案1】:

    好吧,您将需要在某个地方存储数据,因为您不想使用 api 并避免使用不同的视图模型,这是一种选择。

    创建一个名为 City 的 swift 文件并添加:

      struct City: Identifiable {
        let id = UUID()
        let name: String
        let deaths: Int
        let time: String
    }
    

    然后在CityViewModel中创建实例

        let myChosenCities = [City(name: "London", deaths: 3252, time: "8:32"),
                          City(name: "Japan", deaths: 3461, time: "4:21"),
                          City(name: "Canada", deaths: 2352, time: "9:93")
    ]
    

    然后修改你的视图以接受一个像这样初始化的城市。

      struct ToogleView: View {
    
        let city: City
    
    var body: some View {
        ZStack {
            Color.black
                .ignoresSafeArea()
            VStack {
                Spacer()
                Text(city.name)
                    .foregroundColor(.white)
                    .font(.system(size: 24))
                    .bold()
                Spacer()
                Text(city.time)
                    .foregroundColor(.white)
                    .font(.system(size: 18))
                Spacer()
                HStack{
                    Image(systemName: "person.3.fill")
                        .foregroundColor(.white)
                    Text(String(city.deaths))
                        .foregroundColor(.red)
                        .bold()
                }
            Spacer()
            }
        }
      }
    }
    

    然后将您的父视图更改为:

    struct ContentView: View {
        @ObservedObject var vm = CityViewModel()
        
        var body: some View {
            NavigationView {
                ZStack {
                    Color.black
                        .ignoresSafeArea()
                    
                    VStack {
                        List(vm.myChosenCities) { city in
                            NavigationLink(destination: ToogleView(city: city)) {
                            HStack {
                                VStack {
                                    Text(city.name)
                                    Text(city.time)
                                }
                                Text(String(city.deaths))
                            }
                            }
                        }
                    }
                }
            }
        }
    }
    

    你的 viewModel 是这样的:

        class CityViewModel: ObservableObject {
    
        
        let myChosenCities = [City(name: "London", deaths: 3252, time: "8:32"),
                              City(name: "Japan", deaths: 3461, time: "4:21"),
                              City(name: "Canada", deaths: 2352, time: "9:93")
        ]
    
    }
    

    我将您的示例列在一个列表中以便于组织,但您应该能够看到它是如何工作的

    【讨论】:

    • 非常感谢!!! :) 我现在也有了更好的理解。
    • @ObservedObject 仅应在对象的所有者不是视图本身时使用。在此示例中,您应该使用 @StateObject 代替,当视图是 ObservableObject 对象的实际所有者时应该使用它
    【解决方案2】:

    因为您在 ViewModel 中硬编码了伦敦的属性,所以它到处都显示了伦敦的属性。

    我建议创建一个城市模型并将您想要显示的 CityModel 传递到 ToggleView

    以下示例也是非常静态的,如果您想使用城市的动态数据,则需要对其进行调整

    class CityViewModel: ObservableObject {
        @Published var city: [CityModel] = [
            CityModel(title: "London", deaths: 5894, time: "8:36"),
            CityModel(title: "New York", deaths: 2332, time: "3:36")
        ]
    }
    
    struct CityModel {
        var title: String
        var deaths: Int
        var time: String
    }
    

    内容视图

    struct ContentView: View {
        @ObservedObject var cities = CityViewModel()
    
        var body: some View {
            NavigationView {
                ZStack {
                    Color.black
                        .ignoresSafeArea()
    
                    VStack {
    
                        NavigationLink(
                            destination: ToogleView(city: cities.city.first!),
                            label: {
                                Text("London")
                                    .foregroundColor(.white)
                                    .bold()
                                    .font(.system(size: 30))
    
                            })
                        Spacer()
                        NavigationLink(
                            destination: ToogleView(city: cities.city.last!),
                            label: {
                                Text("New York")
                                    .foregroundColor(.white)
                                    .bold()
                                    .font(.system(size: 30))
                            })
                    }
                }
            }
        }
    }
    

    切换视图

    struct ToogleView: View {
        var city: CityModel
    
        var body: some View {
            ZStack {
                Color.black
                    .ignoresSafeArea()
                VStack {
                    Spacer()
                    Text(city.title)
                        .foregroundColor(.white)
                        .font(.system(size: 24))
                        .bold()
                    Spacer()
                    Text(city.time)
                        .foregroundColor(.white)
                        .font(.system(size: 18))
                    Spacer()
                    HStack{
                        Image(systemName: "person.3.fill")
                            .foregroundColor(.white)
                        Text(String(city.deaths))
                            .foregroundColor(.red)
                            .bold()
                    }
                    Spacer()
                }
            }
        }
    }
    

    【讨论】:

    • 感谢沃尔克 :)
    猜你喜欢
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多