SwiftUI: ForEach Unable to infer complex closure return type

Viewed 2004

I'm having a strange issue with the ForEach in SwiftUI.

This is the issue: Unable to infer complex closure return type; add explicit type to disambiguate.

if I remove the ForEach and I use just the List, it works, but I need the ForEach because I would like to implement the .onDelete() modifier

struct SummaryItemsListView: View {

    var items: [CalendarItem]

    var body: some View {
        List {
            ForEach(items, id: \.self) { item  in
//              if 1 > 0 {
                   Text("hey")
                } else {
                   Text("heu")
                }
            }
        }
        .foregroundColor(Color.AgendaColors.foreground)
    }
}



import EventKit

typealias CalendarItem = EKCalendarItem

extension EKCalendarItem: Identifiable {

    public var id: Int {
        return self.hash
    }

    var isTodo: Bool {
        return self is EKReminder
    }

    var isEvent: Bool {
        return self is EKEvent
    }
}
3 Answers

It's because it's getting confused by your conditional statement. Wrap it in a Group instead.

        List {
            ForEach(items, id: \.self) { item  in
                Group {
                    if 1 > 0 {
                        Text("hey")
                    } else {
                        Text("heu")
                    }
                }
            }
        }

I assume you will actually be using your conditional in the future and not just checking an always true statement. Also as Mojtaba mentioned, you can combine your ForEach into the List statement.

Explicitly declare the return type like this,

ForEach(items, id: \.self) { item -> Text  in

If you need some specific modifier like onDelete and you NEED to use ForEach (as you mentioned in comment) you must ensure compiler about the return type.

For example you can achieve this by using ?: operator:

List {
    ForEach(items, id: \.self) { item  in
        1 > 0 ? Text("hey") : Text("heu")
    }
    .onDelete { print($0) }
}

or by explicitly writing the type:

ForEach(items, id: \.self) { item -> Text in
    if 1 > 0 {
        return Text("hey")
    } else {
        return Text("heu")
    }
}

Don't forget to write return keyword

Related