【问题标题】:Creating a series of master detail lists from a single JSON file in SwiftUI在 SwiftUI 中从单个 JSON 文件创建一系列主从列表
【发布时间】:2019-10-31 01:41:25
【问题描述】:

我正在努力了解如何使数据在我正在构建的应用程序中顺畅流动。我只想要一个基本的主详细信息视图,它以所有顶级对象(用户)的列表开始,点击其中一个可以让您查看与该顶级对象(userX -> 城市)相关的所有二级对象,然后点击其中一个可以让您查看所有第三级对象(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()
    }
}

这是助手视图,UserRow:

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 以便我可以从主屏幕向下钻取并获取与我点击的对象相关的列表。

【问题讨论】:

    标签: arrays json swiftui master-detail


    【解决方案1】:

    您的 CityModel 和 TownModel 需要符合 Identifiable,只需像在 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)
            }
        }
    }
    

    我希望这会有所帮助,在我的测试项目中它可以工作!

    【讨论】:

    【解决方案2】:

    首先您必须创建 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

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

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

    struct CityListView: View {
        var cities: [UserModel]
        // list for array of cities
    }
    
    // in UserList
    NavigationLink(destination: CityListView(cities: user.cities)) {
        UserRow(user: user)
    }
    

    附: Apple 为 SwiftUI 中的导航制作了出色的教程:https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation

    【讨论】:

      猜你喜欢
      • 2019-09-26
      • 2013-12-19
      • 1970-01-01
      • 2021-10-16
      • 2016-07-18
      • 1970-01-01
      • 2020-12-27
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多