SwiftUI-属性更改后视图不刷新

时间:2020-01-02 15:09:39

标签: swiftui

我很乐意为此提供帮助,我只是一个初学者,所以不确定我是否误会了,或者实现是否错误或这是一个错误。

成功登录后,我试图将我的MacOS应用选择到主屏幕。我有一个appState与其他应用程序共享状态。 AppState是符合Observable对象的类,并且我添加了一个观察器,以便在isLoggedIn属性更改时进行打印:

class AppState : ObservableObject {
@Published var isLoggedIn = false {
    didSet {
        print("AppState isLoggedin: \(isLoggedIn)")
    }
}
}

我还有一个MasterView结构来处理更改主视图的情况。

struct MasterView: View {

@ObservedObject var appState: AppState = AppState()

var body: some View {

    return Group {

        if appState.isLoggedIn { 
            NavView()  
        } else { 
            LoginView()        
        }

    }.frame(width: 1200, height: 800)
}
}

我有一堆代码来处理登录,为了简洁起见,我不会发布它,足以说明它可以正常工作,将isLoggedIn设置为true并在成功登录后打印到控制台。问题是视图永远不会更新以反映这一点,因此我仍然停留在登录屏幕上。

任何帮助都将不胜感激,我在此方面花费的时间超过了我愿意承认的时间。谢谢!

更新:我记得@EnvironmentObject遇到问题,所以我切换到@ObservableObject和@Published。重新实现@EnvironmentObject之后,我现在记得原因:我有一个网络类,该类会导致崩溃,因为它不是祖先视图。根据Paul Hudson的评论,“注意:环境对象必须由祖先视图提供-如果SwiftUI找不到正确类型的环境对象,则会崩溃。这也适用于预览,因此请小心。” < / p>

For More Information.

1 个答案:

答案 0 :(得分:1)

我知道了,下面的工作代码。

AppState:

final class AppState : ObservableObject {

@Published var isLoggedIn = false {
    didSet {
        print("AppState isLoggedIn: \(isLoggedIn)")
    }
}
}

内容视图:

struct ContentView: View {

@ObservedObject var appState: AppState

var body: some View {

return Group {

    if appState.isLoggedIn {     
        MainView(appState: appState)        
    } else {      
      LoginView(appState: appState)      
    }

}.frame(maxWidth: 1200, maxHeight: 800)
}
}

登录视图:

struct LoginView: View {

@ObservedObject var appState: AppState

var body: some View {

Button(action: {
               withAnimation {
                   self.appState.isLoggedIn.toggle()
               }
           }) {
               Text("Go to Main View")
           }.padding()
}
}

最后,主视图:

struct MainView: View {

@ObservedObject var appState: AppState

var body: some View {

Button(action: {
    withAnimation {
        self.appState.isLoggedIn.toggle()
    }
}) {

    Text("Back To Login View")
}.padding()
}
}