SwiftUI 在 ForEach 循环中获取下一个项目

SwiftUI get next item in ForEach loop

我正在尝试实现一个 VStack 网格,当 ForEach 循环中的下一个项目满足条件时,它需要一个 HStack。我有下面的代码显示数组中的项目,但我不知道如何获取下一个要检查的项目。

这是我目前的情况。

VStack {
            ForEach(item.cards, id: \.self) { item in
                switch item.card.size {
                case .Large:
                    LargeCard(card: item.card, viewModel: CardViewModel())
                case .Medium:
                    MediumCard(card: item.card, viewModel: CardViewModel())
                case .Small:
                    HStack(spacing: 16) {
                        SmallCard(card: item.card, viewModel: CardViewModel())
                        // This is where I think I need to check and I tried somthing like below, but the compiler crashes
                        if [=10=] + 1 < item.cards.count {
                            if item.card.size == .Small {
                                SmallCard(card: item.card, viewModel: CardViewModel())
                            }
                        }
                    }
                case .none:
                    Text("No more.")
                }
            }
        }

这是项目结构:

struct Item: Decodable, Hashable {
    let card: Card
}

这是我想要得到的。

您可以尝试将 id 添加到您的结构 Item,例如:

struct Item: Identifiable, Decodable, Hashable {
    let id = UUID()
    let card: Card
}

然后使用:

VStack {
    ForEach(item.cards, id: \.self) { theItem in
        switch theItem.card.size {
        case .Large:
            LargeCard(card: theItem.card, viewModel: CardViewModel())
        case .Medium:
            MediumCard(card: theItem.card, viewModel: CardViewModel())
        case .Small:
            HStack(spacing: 16) {
                SmallCard(card: theItem.card, viewModel: CardViewModel())
                // here use the id to find the next item
                if let ndx = item.cards.firstIndex(where: {[=11=].id == theItem.id}) {
                    if ndx + 1 < item.cards.count {
                        let nextItem = item.cards[ndx + 1]
                        if nextItem.card.size == .Small {
                            SmallCard(card: nextItem.card, viewModel: CardViewModel())
                        }
                    }
                }
            }
        case .none:
            Text("No more.")
        }
    }
}

您也可以使用评论中提到的枚举,例如:

VStack {
    ForEach(Array(item.cards.enumerated()), id: \.offset) { index, theItem in
        switch theItem.card.size {
        case .Large:
            LargeCard(card: theItem.card, viewModel: CardViewModel())
        case .Medium:
            MediumCard(card: theItem.card, viewModel: CardViewModel())
        case .Small:
            HStack(spacing: 16) {
                SmallCard(card: theItem.card, viewModel: CardViewModel())
                // here use the index to find the next item
                if index + 1 < item.cards.count {
                    let nextItem = item.cards[index + 1]
                    if nextItem.card.size == .Small {
                        SmallCard(card: nextItem.card, viewModel: CardViewModel())
                    }
                }
            }
        case .none:
            Text("No more.")
        }
    }
}

请注意,您似乎应该使用 .environmentObject(viewModel) 通过 单个 CardViewModel() 到视图,而不是每次都创建一个新的 CardViewModel()