【问题标题】:SwiftUI get next item in ForEach loopSwiftUI 在 ForEach 循环中获取下一项
【发布时间】:2022-02-05 19:13:05
【问题描述】:

我正在尝试实现一个 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 $0 + 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
}

这就是我想要的。

【问题讨论】:

  • 您可以使用.enumerated 来拥有和项目和索引,因此可以根据需要使用索引(例如,从容器中访问下一个项目)。接下来可能会有所帮助stackoverflow.com/a/59863409/12299030。
  • 这能回答你的问题吗? Get index in ForEach in SwiftUI
  • 我已经尝试了这两种方法,导致应用程序无法构建而没有任何构建错误,或者编译器只是挂起。如果我注释掉 HStack 中的 if 语句,应用程序就会构建。您可以在 forEach 中的 HStack 中执行 if 块??
  • 你能显示项目的代码吗?它有 id 属性吗?
  • 它没有 ID,但它是一个简单的结构。添加到上面

标签: foreach swiftui


【解决方案1】:

您可以尝试将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: {$0.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.")
        }
    }
}

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

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()。

【讨论】:

  • 当我收到The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions 时,您能否确认它在您的 Xcode 中运行。我已经看到 SwiftUI 在 Xcode 13.2.* 中存在内存泄漏问题,但这是应该编译的简单逻辑。
  • 好吧,我无法编译或运行代码,因为它不完整。缺少的部分太多了。如果您显示所有必需的代码,那么我可以尝试一下。首先显示视图的代码,包括item 的声明。然后我们可以从中取得进展。
  • 标记为答案,因为我在以前的 Xcode 上运行它并且它有效。感谢您的帮助和建议
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2011-12-22
  • 1970-01-01
  • 2021-02-17
相关资源
最近更新 更多