I have implemented a navigation stack and enum following https://stackoverflow.com/a/74362840/21094465 yet I am still receiving the following "A navigationDestination for AppExample.GreaterViewOptions was declared earlier on the stack. Only the destination declared closest to the root view of the stack will be used" when I navigate past the second view.
My enum
enum GreaterViewOptions {
case whatIsNewView
case contentView
case setUpStart
case setUpStepOne
case setUpStepTwo
case connectionSuccessful
case firmwareUpdateView
case registerView
@ViewBuilder func view(_ path: Binding<NavigationPath>) -> some View{
switch self{
case .whatIsNewView:
WelcomeScreenView(path: path)
case .contentView:
ContentView(path: path).environmentObject(SheetManager())
case .setUpStart:
SetupGuideSearchView(path: path)
case .setUpStepOne:
SetupGuideConnectionStepOneView(path: path)
case .setUpStepTwo:
SetupGuideConnectionStepTwoView(path: path)
case .connectionSuccessful:
ConnectionSuccessfulView(path: path)
case .firmwareUpdateView:
FirmwareUpdateView(path: path)
case .registerView:
RegisterView(path: path)
}
}
}
and like I saw, I'm calling it by appending to the path as follows:
Button(action: {
path.append(GreaterViewOptions.whatIsNewView)
}) {
Text("CONTINUE")
.foregroundColor(.white)
}
and so my sequence of views goes as follows (just the first couple)
Initial View
struct BumperScreen: View {
init(viewModel: @autoclosure @escaping () -> BumperScreenViewModel) {
self._viewModel = .init(wrappedValue: viewModel())
}
var body: some View {
NavigationStack(path: $path) {
ZStack {
Color(.trulliGold)
.ignoresSafeArea()
VStack {
if show {
Spacer()
loadAnimation
.frame(width: 150, height: 150)
.task {
try? await viewModel.getDataFromAPI()
try? await Task.sleep(for: Duration.seconds(1))
doneLoading.toggle()
show.toggle()
path.append(GreaterViewOptions.contentView)
}
Spacer()
} else {
launchAnimation
}
}
}
.navigationDestination(for: GreaterViewOptions.self) { option in
option.view($path)
}
}
}
which brings us to our list of policies that you have to check:
struct ContentView: View {
@EnvironmentObject var sheetManager: SheetManager
var body: some View {
ZStack {
Color(.trulliGold)
.ignoresSafeArea()
VStack {
Spacer()
headerStatement
Spacer()
VStack {
privacyPolicy
bluetoothPolicy
locationsPolicy
notificationsPolicy
apprunningPolicy
}
Spacer()
Spacer()
continueButton
}
}
.popup(with: sheetManager)
.navigationBarBackButtonHidden()
}
}
var continueButton: some View {
Button(action: {
path.append(GreaterViewOptions.whatIsNewView)
}) {
Text("CONTINUE")
.foregroundColor(.white)
}
.disabled(!self.areAllChecked)
.padding()
.background(Color.orange)
.foregroundColor(.white)
.clipShape(Capsule())
.padding(.bottom, 32)
}
There's no warning from the BumperScreen to ContentView, but there is the warning I said earlier from ContentView to the third view and views thereafter.
struct WelcomeScreenView: View {
var body: some View {
ZStack {
Color(.gold)
.ignoresSafeArea()
VStack(alignment: .center, spacing: 8) {
header
Spacer()
tabView
Spacer()
Spacer()
nextButton
closeButton
}
}
.navigationBarBackButtonHidden(true)
}
}
I've tried adding the navigationDestination modifier to the Content and Welcome views but the app keeps being sent back to the BumperScreen, leading me to believe that way is wrong.