Question: How can I go from Login()
back to the Home()
without restarting the app/preview? I have a feeling it has to do with the variable not being @State
but I don't know how to make add @State
to a global variable.
Here is my code:
import SwiftUI
var isLoggedIn:Bool {
get {
// Get the standard UserDefaults as "defaults"
let defaults = UserDefaults.standard
// Makes the "welcomeString" variable whatever the saved value for "welcome_string" is
return defaults.bool(forKey: "isLoggedIn")
}
set (newValue) {
// Get the standard UserDefaults as "defaults"
let defaults = UserDefaults.standard
// Saves what the "welcomeString" variable was just set to as the saved value for "welcome_string"
defaults.set(newValue, forKey: "isLoggedIn")
}
}
struct ContentView: View {
var body: some View {
if isLoggedIn {
Home()
} else {
Login()
}
}
}
struct Login: View {
var body: some View {
Button(action: {
isLoggedIn = true
}) {
Text("Click to login")
}
}
}
struct Home: View {
private enum Tab: Hashable {
case schedule
case messaging
case home
case resources
case settings
}
@State private var selectedTab: Tab = .home
var body: some View {
VStack {
TabView(selection: $selectedTab) {
One()
.tag(Tab.home)
.tabItem {
Label("One", systemImage: "note")
}
Two()
.tag(Tab.home)
.tabItem {
Label("Two", systemImage: "note")
}
Three()
.tag(Tab.home)
.tabItem {
Label("Three", systemImage: "note")
}
Four()
.tag(Tab.home)
.tabItem {
Label("Four", systemImage: "note")
}
}
}
}
}
struct One: View {
var body: some View {
Text("One")
}
}
struct Two: View {
var body: some View {
Text("Two")
}
}
struct Three: View {
var body: some View {
Text("Three")
}
}
struct Four: View {
var body: some View {
Button(action: {
isLoggedIn = false
}) {
Text("Logout")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
CodePudding user response:
I do not know why you having this simple issue, you cannot depend on value update of a variable if it is not wrapped with the way SwiftUI works, how ever here is first way for you depending on your approach in your question, do not forget that simulator is not working always correct with UserDefaults, so it may not working in the way that it should, then try use on real device:
struct ContentView: View {
@State private var isLoggedIn: Bool = { return UserDefaults.standard.bool(forKey: "isLoggedIn") }()
var body: some View {
if (isLoggedIn) {
Home(isLoggedIn: $isLoggedIn)
}
else {
Login(isLoggedIn: $isLoggedIn)
}
}
}
func updateLog(_ newValue: Bool) { UserDefaults.standard.set(newValue, forKey: "isLoggedIn") }
struct Login: View {
@Binding var isLoggedIn: Bool
var body: some View {
Button("Tap to login") { isLoggedIn = true; updateLog(true) }
}
}
struct Home: View {
private enum Tab: Hashable {
case schedule
case messaging
case home
case resources
case settings
}
@State private var selectedTab: Tab = .home
@Binding var isLoggedIn: Bool
var body: some View {
VStack {
TabView(selection: $selectedTab) {
One()
.tag(Tab.home)
.tabItem {
Label("One", systemImage: "note")
}
Two()
.tag(Tab.home)
.tabItem {
Label("Two", systemImage: "note")
}
Three()
.tag(Tab.home)
.tabItem {
Label("Three", systemImage: "note")
}
Four(isLoggedIn: $isLoggedIn)
.tag(Tab.home)
.tabItem {
Label("Four", systemImage: "note")
}
}
}
}
}
struct One: View {
var body: some View {
Text("One")
}
}
struct Two: View {
var body: some View {
Text("Two")
}
}
struct Three: View {
var body: some View {
Text("Three")
}
}
struct Four: View {
@Binding var isLoggedIn: Bool
var body: some View {
Button("Logout") { isLoggedIn = false; updateLog(false) }
}
}
Second way:
struct ContentView: View {
@AppStorage("isLoggedIn") var isLoggedIn: Bool = false
var body: some View {
if (isLoggedIn) {
Home()
}
else {
Login()
}
}
}
struct Login: View {
@AppStorage("isLoggedIn") var isLoggedIn: Bool = false
var body: some View {
Button("Tap to login") { isLoggedIn = true }
}
}
struct Home: View {
private enum Tab: Hashable {
case schedule
case messaging
case home
case resources
case settings
}
@State private var selectedTab: Tab = .home
@AppStorage("isLoggedIn") var isLoggedIn: Bool = false
var body: some View {
VStack {
TabView(selection: $selectedTab) {
One()
.tag(Tab.home)
.tabItem {
Label("One", systemImage: "note")
}
Two()
.tag(Tab.home)
.tabItem {
Label("Two", systemImage: "note")
}
Three()
.tag(Tab.home)
.tabItem {
Label("Three", systemImage: "note")
}
Four()
.tag(Tab.home)
.tabItem {
Label("Four", systemImage: "note")
}
}
}
}
}
struct One: View {
var body: some View {
Text("One")
}
}
struct Two: View {
var body: some View {
Text("Two")
}
}
struct Three: View {
var body: some View {
Text("Three")
}
}
struct Four: View {
@AppStorage("isLoggedIn") var isLoggedIn: Bool = false
var body: some View {
Button("Logout") { isLoggedIn = false }
}
}