0

Let's say I have an array that I am appending first with one element in another view, and then appending with the second element from the third view. How to return to the starting view and deduce two additional views from memory?

    struct ContentView: View {
    @State var array: [String] = []
    
    var body: some View {
        NavigationView{
            ScrollView{
                ForEach(array, id: \.self) { element in
                    Text(element)
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    NavigationLink("+") {
                        Details(array: $array)
                    }
                }
            }
        }
    }
}

struct Details: View {
    @Binding var array: [String]
    var body: some View {
        Button(action: { array.append("First Element") }) {
            Text("Append First Element")
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                NavigationLink("+") {
                }
            }
        }
    }
}

struct MoreDetails: View {
    @Binding var array: [String]
    @Environment(\.dismiss) var dismiss

    var body: some View {
        Button(action: { array.append("Second Element") }) {
            Text("Append Second Element")
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                NavigationLink("Done") {
                    ContentView(array: array)
                }
                .simultaneousGesture(TapGesture().onEnded{
                    dismiss()
                })
            }
        }
    }
}
S1mpledev
  • 17
  • 4
  • Are you talking navigation or returning data in the array? – Yrb May 05 '22 at 00:07
  • Returning data in the array. I want the done button to return to the content view with the elements in the array, maybe I did everything wrong – S1mpledev May 05 '22 at 08:48
  • Does this answer your question? [NavigationView inside a TabView Swift UI](https://stackoverflow.com/questions/67237313/navigationview-inside-a-tabview-swift-ui) – Jonas Deichelmann May 05 '22 at 10:04

1 Answers1

0

The issue you are having really is one of navigation, or at least how you think you want to navigate. What you have set up in terms of navigation is this:

Original ContentView -> Details -> MoreDetails -> New ContentView

When what you wanted was:

Original ContentView -> Details -> MoreDetails -> Original ContentView

without having to navigate back through all of the views. To do this, essentially you build a house of cards and then pull the bottom card out, and your navigation collapses back to the original ContentView. Commented code:

struct ContentView: View {
    @State var array: [String] = []
    // originalIsActive is your bottom card, and you will carry a reference
    // through your views like a piece of twine.
    @State var originalIsActive = false
    
    var body: some View {
        NavigationView{
            ScrollView{
                ForEach(array, id: \.self) { element in
                    Text(element)
                }
            }
            .background(
                // This is a programatic NavigationLink that triggers when originalIsActive
                // becomes true. Placed in a background it sits and listens for originalIsActive.
                NavigationLink(isActive: $originalIsActive, destination: {
                    Details(array: $array, originalIsActive: $originalIsActive)
                }, label: {
                    // This is simply a nothing view, so you can't see the NavigationLink.
                    EmptyView()
                })
                // Necessary to prevent link pop back after this NavigationLink
                .isDetailLink(false)
            )
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button {
                        // This Button sets originalIsActive to true, activating the NavigationLink.
                        originalIsActive = true
                    } label: {
                        Image(systemName: "plus")
                    }
                }
            }
        }
    }
}

struct Details: View {
    @Binding var array: [String]
    // Reference to originalIsActive
    @Binding var originalIsActive: Bool
    
    @State var detailsIsActive = false
    
    var body: some View {
        Button(action: { array.append("First Element") }) {
            Text("Append First Element")
        }
        .background(
            NavigationLink(isActive: $detailsIsActive, destination: {
                MoreDetails(array: $array, originalIsActive: $originalIsActive)
            }, label: {
                EmptyView()
            })
            // Necessary to prevent link pop back after this NavigationLink
            .isDetailLink(false)
        )
        .toolbar {
            Button {
                detailsIsActive = true
            } label: {
                Image(systemName: "plus")
            }
        }
    }
}

struct MoreDetails: View {
    @Binding var array: [String]
    // Reference to originalIsActive
    @Binding var originalIsActive: Bool

    var body: some View {
        Button(action: { array.append("Second Element") }) {
            Text("Append Second Element")
        }
        .toolbar {
            ToolbarItem(placement: .navigationBarTrailing) {
                Button {
                    // By setting originalIsActive to false, you pull out the bottom card.
                    // If the first link does not exist, none do.
                    originalIsActive = false
                } label: {
                    Text("Original")
                }

            }
        }
    }
}
Yrb
  • 8,103
  • 2
  • 14
  • 44