我收到与在SwiftUI的ForEach循环中使用提供的索引访问数组中的项目有关的错误。
我有一系列信息,这些信息用于将信息传递给用于渲染卡片的结构。每个HStack我需要两张这些卡,因此我遍历阵列并按如下方式调用这些卡:
ForEach(0..<array.count){item in
Card(name: array[item].name)
Card(name: array[item+1].name)
}
但这会引发错误:The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
我要完成的是在单个VStack中一堆水平堆栈,每个堆栈有2个项目。这样我有2张并排卡的列表。这似乎是蛮力地强行执行该行为的一种简单方法,但是我一直遇到错误。
我可能只是要切换到另一种样式的Hstack,该样式将在添加的每第3行中换行到下一行,但是我仍然想知道是否有人可以告诉我为什么会发生此错误。这似乎是一个简单操作,但编译器无法完成
这是我正在运行的实际代码,如果上面的示例没有剪切它。此代码最奇怪的是,它只会在 SECOND 项+1之后失败。如果我只在代码中执行一次,就可以运行它。
ForEach(0..<self.decks.count){item in
HStack(spacing: 30){
if(item+1 < self.decks.count){
StudyCards(cardTitle: self.decks[item].deckTitle, cardAmt: self.decks[item].stackAmount, lastStdy: self.decks[item].lastStudied)
StudyCards(cardTitle: self.decks[item+1].deckTitle, cardAmt: self.decks[item+1].stackAmount, lastStdy: self.decks[item+1].lastStudied)
}
Spacer()
.padding(.bottom, 4)
} else{
StudyCards(cardTitle: self.decks[item].deckTitle, cardAmt: self.decks[item].stackAmount, lastStdy: self.decks[item].lastStudied)
}
}
}
答案 0 :(得分:0)
正如您所说,我复制了您的错误,仅当您在ForEach中有多个“ item + 1”时才会发生此错误,
Text(self.array[item + 1] + " - " + self.array[item + 1])
因此,我认为问题与您的特定视图无关。一种解决方案是创建一个使item递增并返回视图的函数:
struct ContentView: View {
@State var array: [String] = ["zero","one","two", "three"];
var body: some View {
VStack {
ForEach(0..<array.count) { item in
Text(self.array[item])
if item + 1 < self.array.count {
self.makeView(item: item)
}
}
}
}
func makeView(item: Int) -> Text {
let nextItem = item + 1
return Text(self.array[nextItem] + " - " + self.array[nextItem])
}
}
答案 1 :(得分:0)
好的,我找到了解决方案!
我在这里使用了视图构建器的这种实现方式:(https://www.hackingwithswift.com/quick-start/swiftui/how-to-position-views-in-a-grid)
struct GridStack<Content: View>: View {
let rows: Int
let columns: Int
let content: (Int, Int) -> Content
var body: some View {
VStack(spacing: 30){
ForEach(0 ..< rows, id: \.self) { row in
HStack(spacing: 30){
ForEach(0 ..< self.columns, id: \.self) { column in
self.content(row, column)
}
}
}
}
}
init(rows: Int, columns: Int, @ViewBuilder content: @escaping (Int, Int) -> Content) {
self.rows = rows
self.columns = columns
self.content = content
}
}
然后我像下面这样称呼它。我必须添加if语句,因为如果没有它,它将渲染一张额外的卡。现在,我已经成功实现了具有2列和任意行的网格!无需第三方库!
GridStack(rows: self.rows, columns: 2){ row, col in
if(row*2 + col < self.count){
StudyCards(cardTitle: self.decks[row*2 + col].deckTitle, cardAmt: self.decks[row*2 + col].stackAmount, lastStdy: self.decks[row*2 + col].lastStudied)
}