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

SwiftUI切换视图后修改本地变量导致模型重置问题求助

问题解决:修改DarkMode时ProfileModel状态重置的问题

问题根源

你在ProfileView中用@ObservedObject var profile: ProfileModel = ProfileModel()初始化模型,当修改@AppStorage绑定的isDarkMode时,会触发视图环境变化导致ProfileView重新渲染。此时@ObservedObject会重新创建ProfileModel实例,默认状态回到.profile,所以自动返回了Profile主视图。

解决方案

方案1:用@StateObject保持模型实例

把ProfileView中的@ObservedObject替换为@StateObject,@StateObject会在视图首次创建时初始化一次,后续视图刷新时复用同一个实例,确保状态不丢失:

struct ProfileView: View {
    @EnvironmentObject var authentication: AuthenticationModel
    @StateObject var profile = ProfileModel() // 替换为@StateObject
    var body: some View {
        ZStack {
            switch profile.profileView {
            case .settings:
                SettingsView()
                    .environmentObject(profile)
                    .environmentObject(authentication)
                    .transition(.backslide)
            case .profile:
                // 其他视图代码
            }
        }
    }
}

方案2:全局注入EnvironmentObject(推荐)

如果ProfileModel需要在多个视图间共享,更规范的做法是在App层级初始化并注入:

@main
struct YourApp: App {
    @StateObject private var profile = ProfileModel()
    @StateObject private var authentication = AuthenticationModel()
    
    var body: some Scene {
        WindowGroup {
            ProfileView()
                .environmentObject(profile)
                .environmentObject(authentication)
        }
    }
}

然后在ProfileView中直接通过@EnvironmentObject获取实例,无需自行初始化:

struct ProfileView: View {
    @EnvironmentObject var authentication: AuthenticationModel
    @EnvironmentObject var profile: ProfileModel // 直接使用注入的实例
    var body: some View {
        ZStack {
            switch profile.profileView {
            case .settings:
                SettingsView()
                    .environmentObject(authentication)
                    .transition(.backslide)
            case .profile:
                // 其他视图代码
            }
        }
    }
}

原理说明

  • @ObservedObject仅负责观察对象变化,但不持有对象所有权,视图刷新时会重新创建实例。
  • @StateObject专为持有ObservableObject设计,拥有对象所有权,在视图生命周期内保持实例唯一。
  • @EnvironmentObject用于在视图树中共享对象,需在父视图或App层级注入,确保整个视图树使用同一个实例。

内容的提问来源于stack exchange,提问作者IT-Guy007

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 21:25:20