You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI:如何用其他视图的变量初始化@State变量

解决SwiftUI中用传入变量初始化@State的问题

你的问题根源在于**@State变量的初始化时机早于视图接收外部传入参数的时机**——结构体初始化时,listaElegida还没被正确赋值,自然没法用它来调用Contenido().datos(idLista:)。下面给你两种可行的解决思路:

方法一:利用视图生命周期方法延迟初始化

把@State变量的赋值放到onAppear(或iOS15+的task)里,这时候视图已经加载完成,listaElegida的值已经就绪:

struct ProductosEnLista : View {
    var listaElegida : Listas
    @State var contenido : Array<Contenido> = [] // 先初始化空数组

    var body: some View {
        // 这里放你的视图内容
        Text("Contenido数量: \(contenido.count)")
            .onAppear {
                // 视图出现时加载数据
                contenido = Contenido().datos(idLista: listaElegida.id)
            }
        // 如果是异步加载数据,推荐用iOS15+的task
        // .task {
        //     contenido = await Contenido().datosAsync(idLista: listaElegida.id)
        // }
    }
}

方法二:用@StateObject封装数据逻辑(更推荐)

如果datos方法涉及异步操作或者数据需要后续更新,把数据加载逻辑放到一个ObservableObject类里,用@StateObject管理,代码更清晰还能自动响应数据变化:

class ContenidoViewModel: ObservableObject {
    @Published var contenido: [Contenido] = []
    
    func loadContenido(forListaId id: String) { // 根据你的Listas.id类型调整参数类型
        contenido = Contenido().datos(idLista: id)
        // 异步场景写法:
        // Task {
        //     contenido = await Contenido().datosAsync(idLista: id)
        // }
    }
}

struct ProductosEnLista : View {
    var listaElegida : Listas
    @StateObject private var viewModel = ContenidoViewModel()

    var body: some View {
        Text("Contenido数量: \(viewModel.contenido.count)")
            .onAppear {
                viewModel.loadContenido(forListaId: listaElegida.id)
            }
    }
}

补充:为什么之前的尝试报错?

  • 把listaElegida改成@Binding没用:@Binding只是实现父子视图变量双向绑定,但本质上还是在结构体初始化阶段尝试用它初始化@State,时机依然不对。
  • 在body内直接赋值@State:SwiftUI的body是视图描述逻辑,直接在body里给@State赋值会触发无限刷新循环,违反视图渲染规则,必须通过生命周期方法或ViewModel处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:52:58