我有一个带有嵌套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
、使用if
或switch
,但不能声明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 {
...