ForEach嵌套在List中-当行计数达到特定点时停止生成行



我有一个带有嵌套ForEach循环的列表,应该获取数据,并在行计数器达到3时停止生成行,但我收到以下错误消息

类型"(("不能符合"查看">

一旦我们有三行显示,是否可以切断循环?我的最终目标是一旦显示三行;查看更多";按钮

import SwiftUI
struct RecipeListView: View {
@State var listofRecipes: [RecipeListModel] = RecipeList.recipes
@State private var recipeCounter = 0

init(){
UITableView.appearance().backgroundColor = .clear
}

var body: some View {
VStack{
Text("Recipes")
.padding(.bottom, -20)
//.padding(.top, 40)
.font(.title2)

List{
ForEach(listofRecipes, id: .id){ recipe in
recipeCounter += 1
if(recipeCounter < 3){

HStack{
Image(recipe.image)
.resizable()
.frame (width: 70, height:70)
.cornerRadius(15)

VStack{
Text(recipe.name)
.font(.title2)
//temp solution until I can center it
.padding(.trailing, 25)

NavigationLink(destination: {RecipeController(name: recipe.name, image: recipe.image)}, label: {
Text("View Recipe")
.padding(5)
.foregroundColor(.black)
.background(Color("completeGreen"))
.frame(maxWidth: .infinity)
.cornerRadius(14)

})
.padding(4)

}

}
}
}
}
}
}
}

您的类型不能符合视图,因为您不能更改视图中的变量。您可以声明let、使用ifswitch,但不能声明var或直接更改值,因此不允许使用recipeCounter += 1

一种解决方案是创建一个只包含前3个项目的临时列表,然后在用户决定查看其余项目后将其更改为完整列表

下面的例子对代码的每个部分都做了一些解释:

struct Example: View {

// The full list is a let constant
let fullList = [Recipe("First"),
Recipe("Second"),
Recipe("Third"),
Recipe("Fourth"),
Recipe("Fifth")]

// The list is a @State variable: .onAppear will set
// it to contain the first 3 items, then it'll change
// to the full list
@State private var listofRecipes = [Recipe]()

var body: some View {
VStack{
Text("Recipes")
.font(.title2)
.padding()

List{
ForEach(listofRecipes, id: .id){ recipe in
Text(recipe.text)
}
}

// "Show more" button: will change the list
// to make it contain all the items
Button {
withAnimation {
listofRecipes = fullList
}
} label: {
Text("Show more")
}
}

// When the view appears, set the list to contain only the
// first 3 items
.onAppear {
// Handle case when the list contains only 3 elements or less
if fullList.count > 3 {
listofRecipes = fullList.dropLast(fullList.count - 3)
}
}
}

struct Recipe {
let id = UUID()
let text: String
init(_ text: String) {
self.text = text
}
}
}

正如@HunterLion所提到的,问题是由recipeCounter += 1引起的。

另一种解决方法是在您的条件下直接使用列表索引:

ForEach(listofRecipes.indices) { index in
if(index < 3) {
HStack {
Image(listofRecipes[index].image)
....

另外两人所说的另一种选择是在listofRecipes上使用.propix修饰符。这将返回具有前n个元素的数组的子序列。

ForEach(listofRecipes.prefix(3)) { recipe in
HStack {
...

最新更新