Search code examples
arraysswiftforeachindicesswiftui-foreach

Show specific items in a ForEach loop in Swift


I am very new to Swift and coding in general and I have a question about accessing specific items in an array. I want to only show two items(creatures) from the creatures array in my view instead of returning all of the items. How would I go about doing this?

Here is the view where I want to show only two items(creatures):

struct PlayingCreatures: View {

    
    @EnvironmentObject var data : CreatureZoo
    
    var body: some View {
        
//        Want to only show 2 animals on this screen
            VStack {
                ZStack {
                    ForEach(data.creatures) {creature in
                        Text(creature.emoji)
                            .resizableFont()
                            .offset(creature.offset)
                            .rotationEffect(creature.rotation)
                            .animation(.spring(response: 0.5, dampingFraction: 0.5), value: creature.rotation)
                            .animation(.default.delay(data.indexFor(creature) / 10), value: creature.offset)
                     
                    }
                }
       
                .onTapGesture {
                    data.randomizeOffsets()
                }
           
            }
    }
}

Here is the view where the data is stored:

class CreatureZoo : ObservableObject {
    
 @Published var creatures = [
        Creature(name: "Gorilla", emoji: "🦍"),
        Creature(name: "Peacock", emoji: "🦚"),
        Creature(name: "Squid", emoji: "🦑"),
        Creature(name: "T-Rexxx", emoji: "🦖"),
        Creature(name: "Sloth", emoji: "🦥")
        
        
    ]

}

struct Creature : Identifiable {
    var name : String
    var emoji : String
    
    var id = UUID()
    var offset = CGSize.zero
    var rotation : Angle = Angle(degrees: 0)

// Should be hidden probably
extension CreatureZoo {
    func randomizeOffsets() {
        for index in creatures.indices {
            creatures[index].offset = CGSize(width: CGFloat.random(in: -200...200), height: CGFloat.random(in: -200...200))
            creatures[index].rotation = Angle(degrees: Double.random(in: 0...720))
        }
    }
    
    func synchronizeOffsets() {
        let randomOffset = CGSize(width: CGFloat.random(in: -200...200), height: CGFloat.random(in: -200...200))
        for index in creatures.indices {
            creatures[index].offset = randomOffset
        }
    }
    
    func indexFor(_ creature: Creature) ->  Double {
        if let index = creatures.firstIndex(where: { $0.id == creature.id }) {
            return Double(index)
        }
        return 0.0
    }
}

Solution

  • Use prefix

    ForEach(Array(data.creatures.prefix(2))) {creature in