0

I had a View which should render a GridView in the beta 4 everything worked great but in the beta 5 of Xcode 11 and beta 5 of macOS Catalina it stoped working.

struct List : View {
    var rows: [[Int]]
    var spacing: CGFloat = (screen.width-330)/4
    var list: [ReminderModel]
    var number: Int
    var body: some View {
        return VStack {
            ForEach(rows, id: \.self) { row in
                HStack(spacing: self.spacing) { //The error is at this bracket
                    ForEach(row) { item in
                        Reminder(closed: self.list[item].closed, text: self.list[item].text)
                        self.number % 3 == 0 ? nil : VStack() {
                            self.number-1 == item ? AddReminder() : nil
                        }
                    }
                    Spacer()
                }.padding(.top, self.spacing).padding(.leading, self.spacing)
            }
            if self.number % 3 == 0 {
                HStack() {
                    AddReminder().padding(.leading, self.spacing).padding(.top, self.spacing)
                    Spacer()
                }
            }
        }
    }
}

Error: Unable to infer complex closure return type; add explicit type to disambiguate

Update 1: I found that the problem is this part of the code:

self.number % 3 == 0 ? nil : VStack() {
    self.number-1 == item ? AddReminder() : nil
}

I also tried this but also didn't work:

if (self.number % 3 != 0 && self.number-1 == item) {
    AddReminder()
}
Tobias Bauer
  • 111
  • 2
  • 13
  • Take everything out of the curly braces and put things back a little at a time until you find the actual problem. – matt Jul 31 '19 at 20:24
  • The problem is the second ForEach loop but it worked in beta 4 so I have no plan what to do – Tobias Bauer Jul 31 '19 at 20:25
  • I was in a group yesterday and we were doing SwiftUI programming work. Some had installed Beta 5 in Catalina Beta 4 and they were having problems. This may be part of that. What I would do in hte mean time is NOT use ForEach() and just use the regular for...in – Loren Rogers Jul 31 '19 at 20:31

1 Answers1

1

I simplified your code down into something I could run:

struct ContentView: View {
    var rows: [[Int]] = [[0, 1, 2], [3, 4, 5]]

    var body: some View {
        VStack {
            ForEach(rows, id: \.self) { row in
                HStack {
                    ForEach(row) { item in
                        EmptyView()
                    }
                }
            }
        }
    }
}

...and I got this error:

Referencing initializer 'init(_:content:)' on 'ForEach' requires that 'Int' conform to 'Identifiable'

I'm guessing that in previous betas Int conformed to Identifiable and that beta 5 changed that. So to fix this, just change your second ForEach to ForEach(row, id: \.self).

Update

After removing the parts of your code that I could not run, I managed to get the same error.

Error: Unable to infer complex closure return type; add explicit type to disambiguate

It appears that ForEach is expecting one view to be returned from its body, not multiple as you have here:

ForEach(row) { item in
    Reminder(closed: self.list[item].closed, text: self.list[item].text)
    self.number % 3 == 0 ? nil : VStack() {
        self.number-1 == item ? AddReminder() : nil
    }
}

You're trying to return both a Reminder and an optional VStack, so the compiler can't determine what the return type is supposed to be. This may have worked in the past because ForEach could previously handle tuple views and no longer does - I'm not sure. Whatever the case, you need to first change the ForEach to ForEach(row, id: \.self) as I pointed out earlier, and then you have to wrap everything inside the ForEach in a group, like this:

ForEach(row, id: \.self) { item in
    Group {
        Reminder(closed: self.list[item].closed, text: self.list[item].text)
        self.number % 3 == 0 ? nil : VStack {
            self.number - 1 == item ? AddReminder() : nil
        }
    }
}

One last thing that I've just noticed. The name of your struct should not be List. List already exists in SwiftUI, and you shouldn't name your custom views in ways that will conflict with framework defined types. I would suggest that you rename your view to ReminderList if that adequately describes its purpose.

graycampbell
  • 7,430
  • 3
  • 24
  • 30
  • Well that was an issue with your code, regardless of whether or not it was the only issue. If you really want someone to be able to answer your question, it helps to provide code that we can actually run. – graycampbell Aug 01 '19 at 08:36
  • @TobiasBauer I managed to create a version of your code that I could run, and I've updated my answer with a solution to both errors. Not having `id:` in your `ForEach` was definitely still going to cause problems, so that remains part of the solution. – graycampbell Aug 01 '19 at 10:19
  • Thanks a lot with the id: \.self and the Group it finally worked – Tobias Bauer Aug 01 '19 at 10:46