Jon Vogel
Jon Vogel

Reputation: 5634

Complex Custom Navigation SwiftUI

Here is my current demo UI written in SwiftUI:

enter image description here

I want to make custom navigation and display decisions based on if the cell (View 1, View 2, ...) was tapped or if one of the buttons (arrows) in the cell was tapped.

For example, each cell represents a different view I want to navigate to and each arrow button represents some custom modal I want to present.

How do I keep track of context and propagate the different taps up to the view that will ultimately make the navigation decisions. Here is the view that makes the list and would make the navigation decisions:

import SwiftUI

struct ContentView: View {

    @State var options: [String] = ["View 1", "View 2", "View 3", "View 4"]

    var body: some View {
        ZStack {
            Color.white.edgesIgnoringSafeArea(.all)
            ScrollView {
                ForEach(self.options, id: \.self) { element in
                    OptionCell(optionDescription: element)
                }
            }
        }
    }
}

And here is my OptionCell class. I try and illustrate my problem in some comments in the button action here.

struct OptionCell {
    //MARK: Input Properties
    @State var optionDescription: String

    //MARK: Computed Properties

    //MARK: Init

    //MARK: Functions
    func cellTapped() {
        ///What can I call here to propagate the context of this cell along with the fact that it was tapped to something that needs to make UI transition decisions?
        print("\(self.optionDescription) Tapped")
        //What can I do to make micro navigation decisions if one of the "ArrowButtons" is tapped?
    }
}


extension OptionCell: View {
    var body: some View {
        Button(action: { self.cellTapped() }) {
            VStack {
                HStack{
                    Text(self.optionDescription).foregroundColor(Color.black).padding()
                    Spacer()
                    HStack {
                        //These Views have a Button view in them with a call to a function in that struct. How do I get the call for the tap on each of these buttons propagated up to the decisions making view?
                        ArrowButton(direction: .LEFT)
                        ArrowButton(direction: ArrowDirection.RIGHT)
                        ArrowButton(direction: ArrowDirection.DOWN)
                        ArrowButton(direction: ArrowDirection.UP)
                    }.padding()

                }
                ///Another custom view that I have
                SeparatorView(separatorViewStyle: SeparatorViewStyle.init(weight: .THIN, gapPosition: .RIGHT, color: Colors.grey.medium))
            }
        }
    }
}

In UIKit I would add button actions on the custom UITableViewCell and then create a delegate for the custom cell. Tapping the button would call the appropriate delegate function (Delegate.leftArrow(), Delegate.upArrow(), ...) and the UIViewController would become the delegate for the custom cell and make navigation decisions there.

Upvotes: 0

Views: 357

Answers (1)

I presume the question is:

How do I get the call for the tap on each of these buttons propagated up to the decisions making view?

In ContentView you setup something like this:

@ObservedObject var myChoice = MyChoiceClass()

where:

class MyChoiceClass: ObservableObject {
    @Published var choice: String = ""
}

pass it around to your OptionCell(...) and then to the ArrowButton(...)

So when the ArrowButton(...) change the "choice" it is reflected everywhere.

Upvotes: 1

Related Questions