You need to enable JavaScript to run this app. SwiftUI列表项中如何调用completion handler并解决ViewBuilder报错
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI列表项中如何调用completion handler并解决ViewBuilder报错

报错原因

Closure containing a declaration cannot be used with result builder 'ViewBuilder'报错的直接原因是你在SwiftUI的body属性(被ViewBuilder结果构造器修饰)内部,声明了一个接收array参数的计算属性usersInCohort。ViewBuilder闭包仅允许构造视图的表达式存在,不允许在内部定义带输入参数的函数/计算属性。

除此之外你的代码还存在3个逻辑问题:

  • 同时声明了同名的计算属性和异步请求函数usersInCohort,存在命名冲突
  • 没有对应状态属性存储请求返回的用户列表,请求完成后无法触发视图刷新
  • 没有触发异步请求的时机逻辑,父列表项渲染完成后不会自动调用请求接口
修复方案

步骤1:新增状态属性存储用户列表

在CohortItemView中新增@State属性存储接口返回的用户数据,用于刷新子列表:

@State private var userList: [ProfilesInCohortModel.ProfilesArrayItem] = []
@State private var isLoading = false

步骤2:移除body内的非法声明,调整子列表渲染逻辑

把body内的usersInCohort计算属性移除,直接在VStack中写子列表的渲染逻辑,新增onAppear修饰符触发接口请求:

var body: some View {
    VStack{
        HStack{
            Text(cohortItem.cohort?.name ?? "no data")
                .padding(.leading,10)
                .multilineTextAlignment(.leading)
            Spacer()
            
            ZStack{
                Text("Show all \(cohortItem.profilesNum ?? 0)")
            }.padding(.trailing,10)
        }
        
        // 子列表渲染逻辑
        if isLoading {
            ProgressView()
                .frame(height: 100)
        } else if !userList.isEmpty {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 12){
                    // 避免数组越界,取前5个元素
                    ForEach(userList.prefix(5), id: \.profile.id) { item in
                        let user = item.profile
                        UserCard(user: UserModel(name: user.firstName ?? "", position: user.lastName ?? "", image: "moon.stars.fill"))
                    }
                }.padding(10)
            }
        }
    }
    // 视图渲染完成后自动触发请求
    .onAppear {
        guard !isLoading else { return }
        isLoading = true
        usersInCohort { [weak self] list in
            DispatchQueue.main.async {
                self?.isLoading = false
                self?.userList = list ?? []
            }
        }
    }
}

步骤3:修正异步请求函数的可选值处理

你的请求函数中cohortWebID如果为空会导致请求无效,建议增加空值判断,原有请求逻辑无需额外修改,只需确保回调在主线程赋值即可。

修改完成后,父列表项渲染时会自动触发接口请求,拿到数据后会自动渲染横向滚动的子用户列表,不会再出现编译报错。

内容的提问来源于stack exchange,提问作者Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 14:57:01