0

I am working with on multiple choose answer quiz app.

var itemsTemp = ["ant","bat", "bear", "bee", "bird", "butterfly", "camel", "cat", "cheetah","chick", "chicken"]

Updated Here is example of my quiz app.

  let answerIndex = Int.random(in: 0...3) // for correct answer
  itemsTemp!.shuffle() // to multiple choose option change. 

here is the error:

Thread 1: Fatal error: each layout item may only occur once

Bellow code crashing

LazyVGrid(columns: [GridItem(),GridItem()],spacing: 16) {
       ForEach(itemsTemp) { item in
            VStack {
                    Text(item).id(UUID())
                      .matchedGeometryEffect(id:UUID(), in: namespace, isSource: !show)
                      .onTapGesture{
                               print(" tapped!")
                        }
                    }.matchedGeometryEffect(id: "container\(UUID())", in: namespace)
                 }
              }

it's a quiz app so multiple choose option to select correct answer. array item will be occur in for each loop multiple time.

So need to each layout item multiple occur.

Nazmul Hasan
  • 8,494
  • 5
  • 44
  • 64

2 Answers2

1

For the unique identifier. Use a model array instead of a string array.

First, create a model.

struct Item: Identifiable {
    var id = UUID()
    var name: String
}

then, your array is

var itemsTemp: [Item] = [
    .init(name: "ant"),
    .init(name: "bat"),
    .init(name: "ant"),
    .init(name: "bear"),
    .init(name: "bee"),
    .init(name: "ant"),
    .init(name: "butterfly"),
    .init(name: "bear")
]

Now, your loop is

//Other Code
ForEach(itemsTemp, id:\.id) { item in
    //Other Code
}
//Other Code


The second approach is to use .indices.

//Other Code
ForEach(itemsTemp.indices) { index in
    let item = temsTemp[index]
    //Other Code
}
//Other Code
Raja Kishan
  • 5,529
  • 2
  • 2
  • 15
1

try with a model:

enter image description here

struct Item: Identifiable {
var id = UUID()
var name: String
}


class Model: ObservableObject {
    var items: [Item] = [
        .init(name: "ant"),
        .init(name: "bat"),
        .init(name: "ant"),
        .init(name: "bear"),
        .init(name: "bee"),
        .init(name: "ant"),
        .init(name: "butterfly"),
        .init(name: "bear")
    ]
    @Published var itemsSuffled: [Item] = []
    
    init() {
        shuffle()
    }
    
    func shuffle() {
        itemsSuffled = items.shuffled()
    }
}

struct ContentView: View {
    
    @Namespace private var namespace
    @ObservedObject private var model: Model = Model()
    
    var body: some View {
        
        VStack {
            LazyVGrid(columns: [GridItem(),GridItem()],spacing: 16) {
                ForEach(model.itemsSuffled) { item in
                        VStack {
                            Text(item.name).id(UUID())
                                  .matchedGeometryEffect(id:UUID(), in: namespace, isSource: true)
                                  .onTapGesture{
                                           print(" tapped!")
                                    }
                                }.matchedGeometryEffect(id: "container\(UUID())", in: namespace)
                             }
            }
            Button(action: {
                model.shuffle()
            }, label: {
                Text("new shuffle")
            })
        }
        
    }
}
Simone Pistecchia
  • 2,089
  • 2
  • 13
  • 21