Following the apple tutorial "Scrumdinger" app (
The trouble I'm having is constructing my CardView to properly pull data from the Fleet Model. Once I get the CardView ironed out, everything else should populate appropriately.
Here is my latest attempt at a CardView (with errors):
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)")
}
}
}
}
Here is my Model data... it has an Array within an Array, which is where this diverges from the apple Scrumdinger tutorial:
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
}
}
My parent "PayRateView" should navigate to multiple child "RateDetailView"s for each fleet type:
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")
}
}
}
Here is my PayRateDetailView:
struct RateDetailView: View {
var fleet: [Fleet]
var body: some View {
List {
ForEach (fleet, id: \.fleetName) { line in
RateCardView(fleet: fleet)
}
}
}
}
UPDATE:
CodePudding user response:
The way that you are trying to access the hourly rates in your Fleet
model is the problem. You can access properties using dot-notation.
To retrieve the list of hourly rates (so the [HourlyRates]
) for a fleet, use fleet.rates
. This will be an array of rates, and for each rate, you want to display an HStack
displaying the year
, foHourlyRate
, and captHourlyRate
.
Also take into account the difference between fleet = [Fleet]
and fleet = Fleet
. The former is an array of fleets, meaning fleet.rates
would be a compile error (an array does not have a property called rates
). The latter is a single Fleet
object, which has, as you have defined, a property rates
that can be accessed. This property contains an array of HourlyRates
(i.e. [HourlyRates]
) which can then be looped over using 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)")
}
}
}
}
Regarding the HourlyRates
object
As it stands, you're creating each Fleet
with a single HourlyRates
object that contains arrays of Int
s and Double
s, whereas you want (I assume) an array of HourlyRates
with each a single Int
, Double
, etc. for their property. See below.
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])])
// Should be:
Fleet(fleetName: "B717", rates: [
HourlyRate(year: 1, foHourlyRate: 91, captHourlyRate: 0),
HourlyRate(year: 2, foHourlyRate: 126, captHourlyRate: 235),
HourlyRate(year: 3, foHourlyRate: 148, captHourlyRate: 236),
// ...
]
}