Search code examples
variablesswiftuistateglobal

Passing Variables between Views SwiftUI


Basic questions again: I want to make the variable "anytext" visible and accessible for all future views I am going to add. In my case the variable is going to be a String.

  1. Does the procedure change if it's a Float?
  2. How can I save it as a Global variable?
  3. Does the variable delete itself if I restart the app? And how do I save variables that will remain even after restarting the app?

    import SwiftUI
    
    struct Entry: View {
        
        @State var anytext: String = ""
        
        var body: some View {
            
            VStack {
                
                TextField("Enter text here", text: $anytext)
                    .padding()
                    .border(Color.black, width: 1)
                    .padding()
            }
            
        }
    }
    
    struct Entry_Previews: PreviewProvider {
        static var previews: some View {
            Entry()
        }
    }


Solution

  • Create & pass in an environment object at the root view of your app, or where any 'children' views may need access to anytext. Store anytext as a @Published property in that ObservedObject.

    That's a pointer, but there will be lots of similar questions and stuff. Here is a HWS article which may help.

    Here is an example:

    class MyModel: ObservableObject {
        @Published var anytext = ""
    }
    
    struct ContentView: View {
        @StateObject private var model = MyModel()
    
        var body: some View {
            Entry().environmentObject(model)
        }
    }
    
    struct Entry: View {
        @EnvironmentObject private var model: MyModel
    
        var body: some View {
            VStack {
                TextField("Enter text here", text: $model.anytext)
                    .padding()
                    .border(Color.black, width: 1)
                    .padding()
    
                TextDisplayer()
            }
        }
    }
    
    struct TextDisplayer: View {
        @EnvironmentObject private var model: MyModel
    
        var body: some View {
            Text(model.anytext)
        }
    }
    

    Result:

    Result

    All three views have model which they can access, to get the anytext property.

    To answer your questions:

    1. You use @Published because String, Float, Double etc are all value types.

    2. Using environment objects, as shown here.

    3. They are not persisted, see @AppStorage for saving that.