kiwidiwi
kiwidiwi

Reputation: 35

Share variables across views in iOS app with SwiftUI

I'm new to StackOverflow and SwiftUI programming. So I have this very simple app with a homepage, a settings page and a page where some text is displayed (for now).

The thing I need is for the user to select the app language in the settings page and then:

I sort of get it to work with UserDefaults but when I build the app and test it, the language does not always change and I don't know why and get a bit lost between where to set the UserDefaults and how to access it and how to ensure the data is reloaded after changing it. The idea is to understand how data persistence works and how can a variable defined in a subpage (SettingsPage) be shared with its parent page (the HomePage) and another subpage of the homepage (DetailsPage).

Of course, the idea is for the settings defined by the user to be maintained so that when the user opens the app back, the same language that was last defined remains.

This is my content view:

import SwiftUI

struct ContentView: View {

    var primaryLocale = UserDefaults.standard.string(forKey: "primaryLocale")
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DetailView()) {
                    Text("Detailed view 1")
                }

                Spacer()
                NavigationLink(destination: SettingsIOSView()) {
                    Text("Settings")
                }

                Spacer()
                
                let _ = print(primaryLocale)
                Text(primaryLocale ?? "error")

            }
            .padding()
            .environment(\.locale, .init(identifier: primaryLocale ?? "en"))

        }
    };
    
}



#Preview {
    ContentView()
}

This is the settings page (not all works):

import SwiftUI

struct SettingsIOSView: View {
    @AppStorage("primaryLocale") var primaryLocale = "en"

    @AppStorage("primaryLanguage") var primaryLanguage = "English"

    
    @AppStorage("isDarkMode") private var isDarkMode = false

        
    var body: some View {
        NavigationStack {
            Form {
     
                Picker("Column Layout", selection: $isDualColumn) {
                    Text("Single Column")
                        .tag(false)
                    Text("Double Column")
                        .tag(true)
                }
                .pickerStyle(.inline)            
                
                Picker(selection: $primaryLanguage, label: Text("Primary Language")) {
                    Text("English").tag("English")
                    Text("Spanish").tag("Spanish")
                }
                .onChange(of: primaryLanguage) {
                    if primaryLanguage == "English" {
                        primaryLocale = "en"
                    } else if primaryLanguage == "Spanish" {
                        primaryLocale = "es"
                    }
                }
                         
//                let _ = print(primaryLanguage)

                Section {
                    Toggle("Dark Mode", isOn: $isDarkMode)
                }

            }
            .navigationTitle("Settings")
        }
        .environment(\.locale, .init(identifier: primaryLocale))

        
    }
}

#Preview {
    SettingsIOSView()
}

And this is my DetailsPage:

import SwiftUI

struct DetailView: View {
    
    var primaryLanguage = UserDefaults.standard.string(forKey: "primaryLanguage")
    
    var body: some View {
        NavigationView {                
                HStack {
                    VStack(alignment: .leading) {
                        Text("This is some text")
                        Text(UserDefaults.standard.string(forKey: "primaryLanguage") ?? "Error")
                        Spacer()
                    }
                    //                            Spacer()
                }
                .navigationTitle("Single Column Layout")
        .padding()
        .multilineTextAlignment(.leading) 
        
    }
}


#Preview {
    DetailView()
}

Upvotes: 0

Views: 173

Answers (0)

Related Questions