1

I want to do a project in which a user can write down names in one view. In another view a random name out of these is shown as a text to the user.

I tried doing this with normal referencing, but the array with all the names, that is in the first view, was empty when I tried referencing it in the second view.

The Code looked something like this:

//ContentView:
@State var player1 = ""
@State var array = [String]()

//body:
NavigationView {
            VStack() {
                TextField("name", text: $player1)
                Button("append") {
                    array.append(player1)
                }
                NavigationLink("to next page", destination: secondView())
            }
        }

//secondView:
var ref = ContentView()

//body:
Text(ref.array1[0])

Has anybody got an idea how to make something like this?

Faker HD
  • 21
  • 2
  • Welcome to Stack Overflow. You'd be better off showing your relevant real code rather than edited snippets like this. Also `Text(ref.array1[0])` is not a random element, it's the first element, which could be nil and crash. – Abizern Jul 19 '21 at 17:48
  • There are two main ways you can share data between views. You can use a property wrapper, or you can declare a variable in the second view. The first option is better when you have lots of data, but for just one variable this second option may be better. For the first option vist this: https://www.hackingwithswift.com/quick-start/swiftui/whats-the-difference-between-observedobject-state-and-environmentobject Secondly, you could declare a variable in the second view such as `@Binding var ref: [String]` and then this: `NavigationLink("to next page", destination: secondView(ref = $array))` – Hackinator Jul 19 '21 at 17:52
  • Agree with the above although you don’t need to use @Binding if you are only going to show elements from the array – Joakim Danielson Jul 19 '21 at 18:00
  • Good point @JoakimDanielson – Hackinator Jul 19 '21 at 18:01
  • Have you completed [Apple's SwiftUI tutorial](https://developer.apple.com/tutorials/swiftui)? It goes over this in detail. – Yrb Jul 20 '21 at 00:21

1 Answers1

1

The answer to your question depends on what you want to do with your data once you're in the second view.

If you plan on just spitting out information in the second view, without modifying it, then you can pass the data to your second view through the view struct's initializer.

Method 1: The simpler, non-binding solution

Keep track of all your String inputs using your array variable, wrapped with @State.

struct InputView: View {

    @State var array: [String] = []

    var body: some View {
        // Add your list of string inputs here,
        // as well as your Append button...
    }
}

In your second view, have a property for the String you want to display (with no initialized value).

struct OutputView: View {

    var displayString: String

    var body: some View {
         // Display your String here using Text...
    }
}

Then, in your InputView's body, pass a random element from array into OutputView. In case your array has no elements, you should consider passing a default value.

NavigationLink(destination: OutputView(displayString: array.randomElement() ?? "none") {
    Text("To next page")
}

Method 2: Using Binding to modify in another View

If you need to modify the value after it's passed into your OutputView, consider using Binding.

In your InputView, you can pass the entire array as a Binding<Array<String>> into your OutputView, provided that OutputView is prepared to handle a Binding variable using a @Binding wrapper in your class implementation.

struct OutputView: View {
    @Binding var array: [String]

    // Display a random element from array here.
    // When you modify array, it will also modify the array
    // property that belongs to InputView.
    var body: some View {
         // ...
    }
}

You'll need to use the $ operator to pass the array as Binding<>.

struct InputView: some View {

    @State var array: [String] = []

    var body: some View {
        // ...
        NavigationLink(destination: OutputView(array: $array) {
            Text("To next page")
        }
        // ...
    }
}
Ben Myers
  • 1,173
  • 1
  • 8
  • 25