Home > Software design >  The view does not show up
The view does not show up

Time:07-17

I would like to show a ProgressView when the Button is pressed and the user.showLoginProgress property is set, which is declared as published. However, the new value of the property does not seem to trigger the LoginView to refresh, so the ProgressView does not show up:

struct LoginView: View {
  @EnvironmentObject var user : User

  var body: some View {
    VStack{
      Button("Login", action: {
         user.credentials.showLoginProgress=true  // @Published
      })
      if user.credentials.showLoginProgress{
        ProgressView()  // never shows up
      }
    }
  }
}

The user is global:

var user : User = User()

@main
struct app1App: App {

@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

 var body: some Scene {
    WindowGroup {
        MainView().environmentObject(user)
    }
 }
}

and is defined as:

class User : ObservableObject{
  @Published var credentials = Login()
}

while the credentials is:

class Login : ObservableObject {
  @Published var showLoginProgress : Bool = false
}

Could anyone point out what's wrong with my code?

CodePudding user response:

Try using something like this approach, to re-structure your User and Login, where there is only one ObservableObject and the login functions are in it.

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @StateObject var manager = UserManager()
    var body: some View {
        LoginView().environmentObject(manager)
    }
}

struct LoginView: View {
    @EnvironmentObject var manager: UserManager
    
    var body: some View {
        VStack {
            if manager.user.isAuthorised {
                Text(manager.user.name   " is logged in")
            }
            Button("Login", action: {
                manager.doLogin()
            })
            if manager.showLoginProgress {
                ProgressView()
            }
        }
    }
}

class UserManager: ObservableObject {
    @Published var user = User()
    @Published var showLoginProgress = false
    @Published var someOtherVar = ""
    
    func doLogin() {
        showLoginProgress = true
        // ...
        // simulated login
        DispatchQueue.main.asyncAfter(deadline: .now()   2) {
            self.user.name = "Mickey Mouse"
            self.user.isAuthorised = true
            self.showLoginProgress = false
        }
    }
}

struct User: Identifiable, Hashable {
    let id = UUID()
    var name = ""
    var isAuthorised = false
  //  var credentials: Credentials
    // ....
}
  • Related