【问题标题】:SwiftUI: Using ForEach to dynamically generate a List of array data within an arraySwiftUI:使用 ForEach 在数组中动态生成数组数据列表
【发布时间】:2022-11-10 23:02:17
【问题描述】:

在苹果教程“Scrumdinger”应用程序(https://developer.apple.com/tutorials/app-dev-training/creating-a-navigation-hierarchy)之后,我学到了很多关于在列表中显示数据的知识。但是,我遇到了一个小问题。我的项目的导航层次结构/数据模型与 Scrumdinger 应用程序相比稍微复杂一些。

这是“RateDetailView”所需的结束状态,它是“PayRateView”的子视图。几种飞机机队类型应该有其中之一:

我遇到的麻烦是构建我的 CardView 以正确地从 Fleet Model 中提取数据。一旦我解决了 CardView,其他所有内容都应该正确填充。

这是我对 CardView 的最新尝试(有错误):

struct RateCardView: View {
var fleet: Fleet

var body: some View {
    ForEach(fleet.rates) { rate in
        HStack {
            Text("Year \(rate.year)")
            Spacer()
            Text("\(rate.foHourlyRate)")
            Spacer()
            Text("\(rate.captHourlyRate)")
        }
    }
}
}

这是我的模型数据......它在一个数组中有一个数组,这与苹果的 Scrumdinger 教程不同:

struct Fleet: Identifiable {
let id: UUID
var fleetName: String
var rates: [HourlyRates]

init(id: UUID = UUID(), fleetName: String, rates: [HourlyRates]) {
    self.id = id
    self.fleetName = fleetName
    self.rates = rates
}
}
extension Fleet {
static let fleetList: [Fleet] = [
 Fleet(fleetName: "B717", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "B737-7/8", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "B737-9", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "B757", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "B767-4", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "A220", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "A319/320", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "A321", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "A330", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])]),
 Fleet(fleetName: "A350", rates: [HourlyRates(year: [1,2,3,4,5,6,7,8,9,10,11,12], foHourlyRate: [91,126,148,152,155,159,163,167,169,171,173,174], captHourlyRate: [0,235,236,238,240,242,244,246,248,250,252,254,256])])
]
}
struct HourlyRates: Identifiable {
let id: UUID
var year: [Int]
var foHourlyRate: [Double]
var captHourlyRate: [Double]

init(id: UUID = UUID(), year: [Int], foHourlyRate: [Double], captHourlyRate: [Double]) {
    self.id = id
    self.year = year
    self.foHourlyRate = foHourlyRate
    self.captHourlyRate = captHourlyRate
}
}

我的父母“PayRateView”应该导航到每个车队类型的多个子“RateDetailView”:

struct PayRateView: View {
var fleet: [Fleet]

var body: some View {
    NavigationView {
        List {
            ForEach(fleet, id: \.fleetName) { plane in
                NavigationLink(destination: RateDetailView(fleet: fleet)) {
                    Text(plane.fleetName)
                }
            }
        }
        .navigationTitle("Delta Fleet Pay Rates")
    }
}
}

这是我的 PayRateDetailView:

struct RateDetailView: View {
var fleet: [Fleet]

var body: some View {
    List {
        ForEach (fleet, id: \.fleetName) { line in
            RateCardView(fleet: fleet)
        }
    }
}
}

【问题讨论】:

    标签: arrays list swiftui foreach


    【解决方案1】:

    您尝试在Fleet 模型中访问小时费率的方式是问题所在。您可以使用点表示法访问属性。

    要检索车队的小时费率列表(即[HourlyRates]),请使用fleet.rates。这将是一个费率数组,对于每个费率,您希望显示一个HStack,显示yearfoHourlyRatecaptHourlyRate

    还要考虑fleet = [Fleet]fleet = Fleet 之间的区别。前者是一个大批舰队,这意味着fleet.rates 将是一个编译错误(数组没有名为rates 的属性)。后者是单个Fleet 对象,正如您所定义的,它具有可以访问的属性rates。该属性包含一个HourlyRates 数组(即[HourlyRates]),然后可以使用ForEach 对其进行循环。

    struct RateCardView: View {
        var fleet: Fleet // You are displaying a single fleet's rates, so don't use [Fleet]
    
        var body: some View {
            // ForEach will loop over an array (in this case the array of `HourlyRate`s) and produce a view for each element.
            ForEach(fleet.rates) { rate in
                HStack {
                    Text("Year (rate.year)"
                    Spacer()
                    Text("(rate.foHourlyRate)")
                    Spacer()
                    Text("(rate.captHourlyRate)")
                }
            }
        }
    }
    

    【讨论】:

    • 太感谢了!您很好地解释了我的错误背后的“原因”。我已经更新了我的代码,但现在对于三个 Text() 中的每一个都出现“实例方法 'appendInterpolation(_:formatter:)' 要求 '[Int]' 从 'NSObject' 继承”错误。我已经用新代码和错误图片更新了原始帖子。有任何想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 2021-11-15
    • 1970-01-01
    • 2020-02-13
    • 2022-11-15
    • 1970-01-01
    • 2022-12-09
    相关资源
    最近更新 更多