Search code examples
iosswiftlistswiftuixcode11

Getting errors with building a List view in SwiftUI


For my app I'm trying to make a list out of an array of tuples, but I'm getting the following error:

Cannot invoke initializer for type 'List<_, _>' with an argument list of type '([EggDayList.EggDay], @escaping ([CellDayRow.EggDay]) -> NavigationLink).

I've made a couple of lists before, but I don't see what is going wrong here.

struct EggDayList: View {

    typealias EggDay = (day: Int, mW: Double, measured: Bool, daily: Double)
    var actualWeights : [EggDay] = [
        (1, 35.48, true, 0.00), (2, 35.23, true, 0.00), (3, 34.92, true, 0.00), (4, 34.64, true, 0.00),(5, 34.29, true, 0.00), (6, 33.86, true, 0.00), (7, 33.48, true, 0.00), (8, 33.12, true, 0.00), (9, 32.77, true, 0.00), (10, 32.45, true, 0.00), (11, 32.08, true, 0.00), (12, 31.87, true, 0.00), (13, 31.55, true, 0.00), (14, 31.46, true, 0.00), (15, 31.33, true, 0.00), (16, 31.24, true, 0.00), (17, 31.14, true, 0.00), (18, 31.02, true, 0.00), (19, 30.90, true, 0.00), (20, 30.81, true, 0.00), (21, 30.65, true, 0.00), (22, 30.54, true, 0.00), (23, 30.31, true, 0.00), (24, 30.12, true, 0.00), (25, 29.97, true, 0.00), (26, 29.82, true, 0.00) ]

    var body: some View {

        NavigationView {

            List(actualWeights) { eggDay in
                NavigationLink(destination: EggDetail()) {
                    CellDayRow(eggDay: eggDay)
                }
            }
            .navigationBarTitle("Measurements")
        }
    }
}

struct CellDayRow: View {
    typealias EggDay = (day: Int, mW: Double, measured: Bool, daily: Double)
    let eggDay : [EggDay]
    var body: some View {
        HStack {
            Text("String(eggDay.day)")
                .bold()
                .font(.headline)
            }
    }
}

Solution

  • That error is because actualWeights is not Identifiable and can not be used alone as list argument. You should specify the identifier for each element:

    Xcode 11 beta 5 and above:

    List(actualWeights, id: \.day) { eggDay in Text("Text") }
    

    Xcode 11 beta 4 and below:

    List(actualWeights.identified(by: \.day)) { eggDay in Text("Text") }
    

    But you should have a unique id for each element and create the list based on that. Like this:

    typealias EggDay = (id: String, day: Int, mW: Double, measured: Bool, daily: Double)
    let uniqueEggDay = (UUID().uuidString, 1, 35.48, true, 0.00)
    List([uniqueEggDay], id: \.id) { eggDay in Text("Text") }
    

    I would create a struct for EggDay instead of a tuple and make it conform Identifiable protocol if I where you. It's more convenient and much more cleaner.