Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested ForEach (and List) in Views give unexpected results

Doing a ForEach within another ForEach in a SwiftUI View produces unexpected results - almost like they are stepping on each other's counters. Not clear as to what's happening. I need to display multi branched arrays and have tried a number of variants but keep running into the same problem

I have a few projects where this has come up. Tries using ranges (0..

Is this just a beta issue or am I missing something? I've included an example project that demonstrated the problem.

using XCode 11 Beta (11M392r)

Thanks!

import SwiftUI

struct ContentView: View {

    let topTier:[String] = ["Apple", "Banana", "Cherry"]
    let nextTier:[String] = ["Abalone", "Brie", "Cheddar"]


    var body: some View {
        List {

            ForEach (topTier.indices, id: \.self) { a in

                Text(self.topTier[a])

                ForEach (self.nextTier.indices, id: \.self) { b in

                    Text(self.nextTier[b]).padding(.leading, 20)

                }

            }
        }
    }
}

throws "Ambiguous reference to member 'indices'" on the fitst ForEach.

If the inner ForEach is commented it works displaying the fruits If the outter ForEach is commented it works displaying the cheeses

I want it to display: Apple Abalone Brie Cheddar Banana Abalone Brie Cheddar Cherry Abalone Brie Cheddar

like image 302
user1933275 Avatar asked Sep 09 '19 21:09

user1933275


2 Answers

As with many of the errors that come out of the new @ViewBuilder syntax with SwiftUI during this beta cycle, the “Ambiguous reference…” message is a red herring. Your issue is that the ForEach closure expects a single view, not a view builder.

You can get your view working by simply wrapping the body of the ForEach closure in a Group, like so:

import SwiftUI

struct ContentView: View {

    let topTier:[String] = ["Apple", "Banana", "Cherry"]
    let nextTier:[String] = ["Abalone", "Brie", "Cheddar"]


    var body: some View {
        List {

            ForEach (topTier.indices, id: \.self) { a in
                Group {
                    Text(self.topTier[a])

                    ForEach (self.nextTier.indices, id: \.self) { b in

                        Text(self.nextTier[b]).padding(.leading, 20)

                    }
                }
            }
        }
    }
}

And voilà:

enter image description here

like image 134
marcprux Avatar answered Nov 17 '22 10:11

marcprux


Not sure I completely understand your problem, but I had a similar, potentially related issue. SwiftUI Nested ForEach causes unexpected ordering

I received an answer that specified that each of the cells need a different identifier, which could also be your problem.

Each time the nested ForEach is executed, the id's that are generated are the same, which results in there being lots of cells that have the same ID, and thus the unexpected reorderings etc. appear. In the linked post you can see how I solved this issue.

Summary: Each cell needs a unique ID, as you can see in this screenshot where each of the cells from section 7 and 8 have different ids.

like image 2
charelf Avatar answered Nov 17 '22 10:11

charelf