1

I am creating a SwiftUI app with a wizard-like navigation. I have already build a WizardView, in which I then embed the single pages. The WizardView should take care of general stuff like displaying everything in a nice looking frame, display navigation buttons, and so on. Basically everything seems to look right, so I started to have a look at how navigation works in SwiftUI.

This is a condensed version of what I ended up with. The problem is, I can't find a possible solution for passing the nextView from the concrete page to the WizardView struct.

import SwiftUI

struct WizardView<Content: View>: View {
    
    private let content: () -> Content
    
    private var canNavigateBack: Bool
    private var canNavigateForth: Bool
    
    // TODO
    // How do I pass this as parameter, which has to be optional or some default view,
    // as the last screen won't have a next one.
    private var nextView = EmptyView()
    
    init(canNavigateBack: Bool? = true,
         canNavigateForth: Bool? = true,
         @ViewBuilder content: @escaping () -> Content) {
        
        self.canNavigateBack = canNavigateBack!;
        self.canNavigateForth = canNavigateForth!;
        self.content = content
    }

    var body: some View {
        VStack(spacing: 15) {
            content()
            
            HStack {
                // TODO Implement correct back button
                if (canNavigateBack) {
                    NavigationLink(destination: EmptyView()) {
                        Text("Back")
                    }
                }
                
                if (canNavigateBack && canNavigateForth) {
                    Spacer()
                }
            
                // Naviate to next screen
                if (canNavigateForth) {
                    NavigationLink(destination: nextView) {
                        Text("Next")
                    }
                }
            }
        }
        .padding()
    }
}

struct DemoView_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            /**
             * The usage within the different screens should be something like this
             */
            Divider()
            
            WizardView(canNavigateBack: false) {
                Text("This would be the first screen, without back navigation.")
            }
            
            Divider()

            WizardView() {
                Text("This would be another screen.")
            }

            Divider()
            
            WizardView(canNavigateForth: false) {
                Text("This is the last screen, without next button.")
            }
            
            Divider()
        }
    }
}

I am fairly new to Swift and SwiftUI so maybe I just don't understand some basic concepts here.

Update:

Here I found something, that helped me, at least a little. SwiftUI MVVM Coordinator/Router/NavigationLink

I will update this, question as soon, as I made my way through.

Jan Held
  • 634
  • 4
  • 14
  • 1
    Consider this solution https://stackoverflow.com/a/62909832/12299030 – Asperi Aug 20 '20 at 14:29
  • Thanks for the hint. Very interesting post. I found another link in it, which helped me for my case. Looks very much like my first tries, but I must have done something wrong back then. Now it works like a charm to pass a seconds @ViewBuilder parameter with the desired destination. – Jan Held Aug 21 '20 at 07:59

0 Answers0