Home > front end >  Shuffle inside a ForEach SwiftUI
Shuffle inside a ForEach SwiftUI

Time:04-13

If a do a very simple ForEach loop I'm able to use a shuffle parameter to shuffle the things inside.

Something linke this:

 var plays: [Play] = playData
    
    var body: some View {
NavigationView {
            ScrollView {
                ForEach(plays.shuffled()) { item in
                    NavigationLink {
                        PlayDetailView(play: item)
                    } label: {
                        PlayCard(play: item)
                            .padding(.vertical, 7)
                    }
                }
            }

But when I use an Environment object and call something different inside the loop, I don't have the option to shuffle things.

Can someone point me in the right direction to shuffle the results of the following loops?

var body: some View {
        LazyVGrid(columns: [GridItem(.adaptive(minimum: 160), spacing: 15)]) {
            ForEach(0..<modelData.stories.count, id: \.self) { item in
                if modelData.stories[item].featured == true {
                    NavigationLink {
                        StoryDetails(story: modelData.stories[item])
                    } label: {
                        GeneralCard(story: modelData.stories[item])
                    }
                    
                }
            }
        }
    }

Here is the ModelData:

struct Story: Hashable, Codable, Identifiable {
    var id: Int
    var title: String
    var description: String
    var featured: Bool
    var paid: Bool
    var featuredImage: String
    var bigImage: String
    var text: [String]
    var category: Category

}

CodePudding user response:

You are creating a closed range and iterating over it, accesing the data by index. Thats in it self not a good practice. It would be easier if you iterate over the collection itself.

ForEach(modelData.stories.shuffled()) { story in
            if story.featured == true {
                NavigationLink {
                    StoryDetails(story: story)
                } label: {
                    GeneralCard(story: story)
                }
            }
            

You don´t need the initializer with the id here. Your Story items allready conform to Identifiable.

  • Related