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

SwiftUI多影片视图Date属性不更新问题求助

问题根源

你遇到的问题是手动初始化State实例导致状态意外共享。SwiftUI中,@State的底层存储(即_releaseDate)必须由框架管理,不能在自定义init里直接赋值。手动创建State(initialValue:)会让多个视图实例复用同一份状态,所以所有视图始终显示第一个影片的日期。

解决方案

方案1:用计算属性替代State(推荐)

转换后的日期完全依赖film的releaseDate,属于派生值,不需要状态管理。直接用计算属性即可:

struct FilmView: View {
    let film: FetchFilmsQuery.Data.AllFilms.Film
    
    private var releaseDate: Date? {
        let inputDateFormatter = DateFormatter()
        inputDateFormatter.dateFormat = "yyyy-MM-dd"
        return film.releaseDate.flatMap { inputDateFormatter.date(from: $0) }
    }

    // 视图主体代码...
}

每次渲染视图时,都会基于当前film重新计算日期,彻底解决状态共享问题。

方案2:正确初始化@State(若需修改日期)

如果后续需要修改这个日期,必须让SwiftUI正确管理State的存储:

struct FilmView: View {
    let film: FetchFilmsQuery.Data.AllFilms.Film
    @State private var releaseDate: Date?
    
    init(film: FetchFilmsQuery.Data.AllFilms.Film) {
        self.film = film
        let inputDateFormatter = DateFormatter()
        inputDateFormatter.dateFormat = "yyyy-MM-dd"
        let initialDate = film.releaseDate.flatMap { inputDateFormatter.date(from: $0) }
        // 使用规范的wrappedValue初始化,确保状态与视图实例绑定
        _releaseDate = State(wrappedValue: initialDate)
    }

    // 视图主体代码...
}
额外优化

重复创建DateFormatter会浪费性能,把它定义为静态属性复用:

struct FilmView: View {
    let film: FetchFilmsQuery.Data.AllFilms.Film
    
    private static let inputDateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }()
    
    private var releaseDate: Date? {
        film.releaseDate.flatMap { Self.inputDateFormatter.date(from: $0) }
    }

    // 视图主体代码...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:14:56