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

SwiftUI中如何从其他视图传入参数初始化指定大小的数组?

解决SwiftUI中根据传入参数初始化固定大小@State数组的问题

你遇到的报错核心原因是:Swift的属性初始化器会在实例(self)创建前执行,所以没法在属性初始化阶段直接引用其他实例属性(比如loopStartDate、dateArray)来初始化@State变量。

下面是两种可行的解决方式:

方法一:通过自定义初始化方法初始化

在SecondaryView的自定义init里先计算出日期数组和天数,再初始化@State变量:

struct SecondaryView: View {
    // 从主视图传入的日期参数
    let loopStartDate: Date
    let loopEndDate: Date
    
    // 存储日期数组
    let dateArray: [Date]
    // 初始化@State数组
    @State private var names: [String?]
    
    init(loopStartDate: Date, loopEndDate: Date) {
        self.loopStartDate = loopStartDate
        self.loopEndDate = loopEndDate
        // 计算日期数组
        self.dateArray = Date.dates(from: loopStartDate, to: loopEndDate)
        // 初始化对应大小的可选字符串数组
        self._names = State(initialValue: [String?](repeating: nil, count: dateArray.count))
    }
    
    var body: some View {
        // 你的视图内容示例
        Text("总天数:\(dateArray.count)")
    }
}

// 假设你已实现的日期扩展方法
extension Date {
    static func dates(from start: Date, to end: Date) -> [Date] {
        var dates: [Date] = []
        var currentDate = start
        while currentDate <= end {
            dates.append(currentDate)
            guard let nextDate = Calendar.current.date(byAdding: .day, value: 1, to: currentDate) else { break }
            currentDate = nextDate
        }
        return dates
    }
}

注意:初始化@State变量时需要用_names(下划线+属性名),直接赋值State的初始值,这是SwiftUI中在init里初始化@State的标准写法。

方法二:使用.onAppear延迟初始化

如果不想写自定义init,可以把dateArray改成计算属性,然后在视图出现时初始化names数组:

struct SecondaryView: View {
    let loopStartDate: Date
    let loopEndDate: Date
    
    // 计算属性:每次访问时计算日期数组
    var dateArray: [Date] {
        Date.dates(from: loopStartDate, to: loopEndDate)
    }
    
    @State private var names: [String?] = []
    
    var body: some View {
        Text("总天数:\(dateArray.count)")
            .onAppear {
                // 视图首次出现时初始化数组
                if names.isEmpty {
                    names = [String?](repeating: nil, count: dateArray.count)
                }
            }
            .onChange(of: loopStartDate) { _ in
                // 日期参数变化时重新初始化数组
                names = [String?](repeating: nil, count: dateArray.count)
            }
            .onChange(of: loopEndDate) { _ in
                names = [String?](repeating: nil, count: dateArray.count)
            }
    }
}

这种方式代码更简洁,但要通过.onChange监听日期参数的变化,确保数组大小能同步更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:25:16