首页 > 解决方案 > SwiftUI @ObservedObect 没有更新

问题描述

我有一个基于从 Firebase RemoteConfig 获得的布尔值显示或不显示文本的内容视图。我正在尝试在 SecondView 上传递布尔值,并且我希望它在 ContentView 上的布尔值更新时自行更新。

class GlobalString: ObservableObject {
    @Published var isHidden = true
}

struct ContentView: View {
    @ObservedObject var globalString = GlobalString()
    
func updateUI(newUI: Bool) {
    if newUI {
        globalString.isHidden = false
    }
    else {
        globalString.isHidden = true
    }
}
func fetchValues() {
        let value = self.remoteConfig.configValue(forKey: "show_boost").boolValue
        updateUI(newUI: value)
    }
    
    init() {
        fetchValues()
    }
    
    var body: some View {
    if !globalString.isHidden {
        Text("Not Hidden")
    else {
        Text("Hidden")
    }
  }
}

问题是当我更改 ContentView 上的布尔值(通过 RemoteConfig)时,我的 SecondView 中的布尔值没有更新。而且我不知道为什么...

struct SecondView: View {
    
    @ObservedObject var globalString = GlobalString()

    var body: some View {
        VStack {
            if globalString.isHidden {
                Text("Hidden")
            else {
                Text("Not Hidden")
            }
         }
     }
  }
}

标签: swiftuifirebase-remote-config

解决方案


其中每一个都是@ObservedObject var globalString = GlobalString()全局模型的一个单独实例。

一个人看不到另一个人在做什么。

class GlobalString: ObservableObject {
    @Published var isHidden = true
    
    init() {
        fetchValues()
    }
    //This kind of stuff shouldn't be in a View it can't be shared/reused.
    func fetchValues() {
        let value = self.remoteConfig.configValue(forKey: "show_boost").boolValue
        updateUI(newUI: value)
    }
    
    func updateUI(newUI: Bool) {
        if newUI {
            self.isHidden = false
        }
        else {
            self.isHidden = true
        }
    }
}
struct SampleUpdateParentView: View {
    //@ObservedObject is for when then instance is initialized in another View
    @StateObject var globalString = GlobalString()
    
    var body: some View {
        //This is how you share an instance
        SampleUpdateView().environmentObject(globalString)
        SecondView().environmentObject(globalString)
    }
}
struct SampleUpdateView: View {
    @EnvironmentObject var globalString: GlobalString
    var body: some View {
        if !globalString.isHidden {
            Text("Not Hidden")
        }else {
            Text("Hidden")
        }
    }
}
struct SecondView: View {
    @EnvironmentObject var globalString: GlobalString
    
    var body: some View {
        VStack {
            if globalString.isHidden {
                Text("Hidden")
            }else {
                Text("Not Hidden")
            }
        }
    }
}

您也可以使用单例(不太推荐),只需更改/替换您initclass GlobalString

static let shared = GlobalString()
private init() {
    fetchValues()
}

并更改您的实例以引用该shared变量。

@StateObject var globalString = GlobalString.shared

推荐阅读