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

SwiftUI视图未随ObservableObject状态变化更新问题求助

问题解决:SwiftUI多视图状态切换不响应的修复

你的问题核心在于没有正确让SwiftUI监听ObservableObject的状态变化,以及没有在子视图中正确引用共享状态。以下是具体修复步骤:

1. 修正App入口的状态监听逻辑

在MoodyApp.swift中,需要用@StateObject(用于持有ObservableObject实例)来管理全局状态,并将其注入到环境中,让子视图可访问,同时基于监听的状态切换视图:

import SwiftUI

@main
struct MoodyApp: App {
    // 用@StateObject持有ObservableObject实例,SwiftUI会自动监听其@Published属性变化
    @StateObject private var globalVars = GlobalVars()
    
    var body: some Scene {
        WindowGroup {
            // 根据监听的状态切换视图
            if globalVars.isSettings {
                SettingsView()
            } else {
                MainView()
            }
            // 将全局状态注入环境,让所有子视图可以访问
            .environmentObject(globalVars)
        }
    }
}

2. 在MainView中引用并修改全局状态

在MainView中,通过@EnvironmentObject获取共享状态实例,在点击事件中修改isSettings:

import SwiftUI

struct MainView: View {
    // 从环境中获取全局状态
    @EnvironmentObject var globalVars: GlobalVars
    
    // colors
    let darkGrey : Color = Color(red: 62/255, green: 62/255, blue: 62/255);
    let grey : Color = Color(red: 86/255, green: 86/255, blue: 86/255);
    let lightGrey : Color = Color(red: 117/255, green: 117/255, blue: 117/255);
    let dayGrey : Color = Color(red: 206/255, green: 206/255, blue: 206/255);
    let white : Color = Color(red: 242/255, green: 242/255, blue: 242/255);
    
    let years = Callendar();
    
    var body: some View {
        VStack(){
            VStack{
                HStack{
                    Text("menu")
                        .foregroundColor(white)
                        .padding()
                    Spacer()
                    Text("settings")
                        .foregroundColor(white)
                        .padding()
                        .onTapGesture(){
                            // 修改全局状态的isSettings,SwiftUI会自动刷新相关视图
                            globalVars.isSettings.toggle()
                        }
                }
                .ignoresSafeArea()
                .frame(height: 0.0)
                HStack{
                    Text("2023")
                        .font(.system(size:36))
                        .foregroundColor(white)
                }
            }.background(darkGrey)
            ScrollView(showsIndicators: false){
                ForEach(0..<12) { index in
                    Text(years.month[index])
                        .font(.system(size:36))
                        .foregroundColor(white)
                        .padding(.bottom, -8)
                        ZStack{
                            RoundedRectangle(cornerRadius: 45, style: .continuous)
                                .fill(lightGrey)
                                .frame(width: 320, height: 320)
                            ForEach(0..<years.quantity[index], id: \.self){ value in
                                let x = CGFloat(years.positionX[index][value])
                                let y = CGFloat(years.positionY[index][value])
                                RoundedRectangle(cornerRadius: 7, style: .continuous)
                                    .fill(dayGrey)
                                    .frame(width: 30, height: 30)
                                    .position(x: x, y: y);
                                Text(String(value+1))
                                    .position(x: x, y: y)
                                    .foregroundColor(.black);
                            }
                        }
                    
                    }
                }
        }.background(grey)
            .statusBar(hidden: true)
    }
}

struct MainView_Previews: PreviewProvider {
    static var previews: some View {
        // 预览时需要注入环境对象
        MainView()
            .environmentObject(GlobalVars())
    }
}

3. 优化GlobalVars文件(移除全局变量)

删除全局vars变量,改用@StateObject+environmentObject的方式共享状态,更符合SwiftUI状态管理规范:

import Foundation
import SwiftUI // 导入SwiftUI以使用ObservableObject

class GlobalVars: ObservableObject {
    @Published var isSettings = false
}

// 删除全局变量:var vars = GlobalVars()

问题根源说明

  • 直接访问全局vars.isSettings时,SwiftUI不会自动监听其@Published属性变化,必须通过@StateObject/@ObservedObject/@EnvironmentObject持有实例,才能让SwiftUI建立订阅并在状态变化时刷新视图。
  • @State仅适用于值类型(如Bool、结构体),不能用于ObservableObject这类引用类型,之前的@State var globalVars = vars属于错误用法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 00:25:22