Arrays 在SwiftUI中从单个JSON文件创建一系列主详细信息列表

Arrays 在SwiftUI中从单个JSON文件创建一系列主详细信息列表,arrays,json,swiftui,master-detail,Arrays,Json,Swiftui,Master Detail,我试图通过理解如何通过我正在构建的应用程序使数据顺畅地流动来工作。我只想要一个基本的主细节视图,从所有顶级对象(用户)的列表开始,点击其中一个可以看到与该顶级相关的所有二级对象(userX->cities),点击其中一个可以看到所有三级对象(userX->cityX->towns) 这是我的JSON文件: [ { "id": 1001, "first_name": "Jimmy", "last_name": "Simms",

我试图通过理解如何通过我正在构建的应用程序使数据顺畅地流动来工作。我只想要一个基本的主细节视图,从所有顶级对象(用户)的列表开始,点击其中一个可以看到与该顶级相关的所有二级对象(userX->cities),点击其中一个可以看到所有三级对象(userX->cityX->towns)

这是我的JSON文件:

[
    {
        "id": 1001,
        "first_name": "Jimmy",
        "last_name": "Simms",
        "cities": [{
                "name": "New York City",
                "towns": [{
                        "name": "Brooklyn"
                    },
                    {
                        "name": "Manhatten"
                    }
                ]
            },
            {
                "name": "Tokyo",
                "towns": [{
                        "name": "Churo"
                    },
                    {
                        "name": "Riponggi"
                    }
                ]
            }
        ]
    }
...
]
我有一个模型,我认为它可以很好地用于此:

import SwiftUI

struct UserModel: Codable, Identifiable {
    let id: Int
    let firstName: String
    let lastName: String
    let cities: [CityModel]

    enum CodingKeys: String, CodingKey {
        case id
        case firstName = "first_name"
        case lastName = "last_name"
        case cities
    }
}

struct CityModel: Codable {
    let name: String
    let towns: [TownModel]
}

struct TownModel: Codable {
    let name: String
}
然而,我正在努力做的是将这一切构建到一系列相互连接的列表视图中。我有最高级的一个,UserList.swift,至少显示了一个用户列表

import SwiftUI

struct UserList: View {
    var body: some View {
        NavigationView {
            List(userData) { user in
                NavigationLink(destination: UserRow(user: user)) {
                    UserRow(user: user)
                }

            }
            .navigationBarTitle(Text("Users"))
        }
    }
}

struct UserList_Previews: PreviewProvider {
    static var previews: some View {
        UserList()
    }
}
它是助手视图,用户行:

import SwiftUI

struct UserRow: View {
    var user: UserModel
    var body: some View {
        HStack {

            VStack(alignment: .leading) {
                Text(user.firstName)
                    .font(.headline)

                Text(user.lastName)
                    .font(.body)
                    .foregroundColor(Color.gray)

            }
            Spacer()
        }
    }
}

struct UserRow_Previews: PreviewProvider {
    static var previews: some View {
        UserRow(user: userData[0])
    }
}
UserList.swift预览:


我搞不懂的是如何编写CityList/CityRow和TownList/TownRow,这样我就可以从主屏幕向下钻取与我点击的对象相关的列表。

首先你必须创建CityList视图和CityRow,就像你为用户做的那样:

struct CityListView: View {
    var user: UserModel
    var body: some View {

            // don't forget to make CityModel Identifiable 
            List(user.cities) { city in
                CityRowView(city: city)
            }
            .navigationBarTitle(Text("Cities"))
        }
    }
}

struct CityRowView: View {
    var city: CityModel
    var body: some View {
        HStack {
            Text(city. name)
                .font(.headline)
            Spacer()
        }
    }
}

之后,您需要在NavigationLink中更改目的地(不是UserRow,而是新建CityListView

另一种方法是将变量“cities”声明为CityModel数组,并从用户处接收它:

struct CityListView: View {
    var cities: [UserModel]
    // list for array of cities
}

// in UserList
NavigationLink(destination: CityListView(cities: user.cities)) {
    UserRow(user: user)
}

另外,苹果为SwiftUI中的导航制作了优秀的教程:

首先,你必须创建CityListView和CityRow,就像你为用户所做的那样:

struct CityListView: View {
    var user: UserModel
    var body: some View {

            // don't forget to make CityModel Identifiable 
            List(user.cities) { city in
                CityRowView(city: city)
            }
            .navigationBarTitle(Text("Cities"))
        }
    }
}

struct CityRowView: View {
    var city: CityModel
    var body: some View {
        HStack {
            Text(city. name)
                .font(.headline)
            Spacer()
        }
    }
}

之后,您需要在NavigationLink中更改目的地(不是UserRow,而是新建CityListView

另一种方法是将变量“cities”声明为CityModel数组,并从用户处接收它:

struct CityListView: View {
    var cities: [UserModel]
    // list for array of cities
}

// in UserList
NavigationLink(destination: CityListView(cities: user.cities)) {
    UserRow(user: user)
}

另外,苹果为SwiftUI中的导航制作了出色的教程:

你的城市模型和城市模型需要符合可识别的标准,只需像在UserModel中那样为它们添加一个id即可

然后您需要编辑UserList NavigationLink:

NavigationLink(destination: CityList(cities: user.cities)) {
    Text(user.firstName)
}
导航现在是这样的:UserList->CityList->TownList

城市列表:

struct CityList: View {

    var cities: [CityModel]

    var body: some View {
        List (cities) { city in
            NavigationLink(destination: TownList(towns: city.towns)) {
                Text(city.name)
            }
        }
    }
}
市民名单:

struct TownList: View {

    var towns: [TownModel]

    var body: some View {
        List (towns) { town in
            Text(town.name)
        }
    }
}

我希望这有帮助,在我的测试项目中它是有效的

您的CityModel和TownModel需要符合Identificated,只需像在UserModel中那样为它们添加一个id即可

然后您需要编辑UserList NavigationLink:

NavigationLink(destination: CityList(cities: user.cities)) {
    Text(user.firstName)
}
导航现在是这样的:UserList->CityList->TownList

城市列表:

struct CityList: View {

    var cities: [CityModel]

    var body: some View {
        List (cities) { city in
            NavigationLink(destination: TownList(towns: city.towns)) {
                Text(city.name)
            }
        }
    }
}
市民名单:

struct TownList: View {

    var towns: [TownModel]

    var body: some View {
        List (towns) { town in
            Text(town.name)
        }
    }
}

我希望这有帮助,在我的测试项目中它是有效的

@FuegoDeBassi谢谢你!如果你需要帮助,请告诉我!哈,如果你对这个有什么想法@谢谢你!如果你需要帮助,请告诉我!哈,如果你对这个有什么想法。。。