I have a view A that contains a NavigationView. A pushes View B by activating a NavigationLink. B pushes View C by activating a NavigationLink. C pushes View D by tapping a NavigationLink. D then presents a View as a sheet. If i dismiss the sheet the current top view is B. For some reason presenting the sheet pops 2 screens.
Can someone explain this behaviour and how i can fix it? I'm guessing somehow the navigation link in view B (that pushed view C) get deActivated but I cant figure out why
From what i tested it seems when the sheet gets presented ViewB gets reinitialized which will reinit my vm and so deactivate the link. How to i stop the view from being reinitialized?
struct ViewA: View {
@SwiftUI.Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
@ObservedObject private var viewModel: ViewAVM
var body: some View {
NavigationView {
GeometryReader { fullView in
ScrollView(.vertical, showsIndicators: false) {
if !self.viewModel.loading {
VStack(alignment: .leading, spacing: 0) {
DetailsView(car: self.$viewModel.data)
Spacer(minLength: 20)
NavigationLink(destination: ViewB(rootActive: self.$viewModel.showB), isActive: self.$viewModel.showB) {
Button(action: {
self.viewModel.showB = true
}) {
SecondaryButtonView(enabled: true, title: "Go")
}
}.isDetailLink(false).padding([.leading, .trailing], 20)
}.frame(minHeight: fullView.size.height)
}
}
}
.navigationBarBackButtonHidden(true)
.navigationBarTitle("View A")
.navigationBarItems(leading: Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Image("LeftArrow").renderingMode(.original)
})
.onAppear {
self.viewModel.update()
}
}
.navigationBarTitle("")
.navigationBarHidden(true)
}
}
struct ViewBUI: View {
@SwiftUI.Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
@ObservedObject private var viewModel: ViewBVM
private let rootActive: Binding<Bool>
var body: some View {
GeometryReader { fullView in
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .leading, spacing: 0) {
Text("").font(.regularParagraph).padding(.top, 15).padding(.bottom, 10)
CustomEntryView()
Spacer(minLength: 20)
NavigationLink(destination: ViewC(rootActive: self.rootActive), isActive: self.$viewModel.showC) {
Button(action: {
self.hideKeyboard()
self.viewModel.validate()
}) {
PrimaryButtonView(enabled: self.viewModel.valid, title: "Continue")
}.disabled(!self.viewModel.valid)
}.isDetailLink(false).padding(.bottom, 16)
}.padding([.leading, .trailing], 20).frame(minHeight: fullView.size.height)
}
}
.navigationBarBackButtonHidden(true)
.navigationBarTitle(viewModel.new ? "New" : "Old")
.navigationBarItems(leading: Button(action: {
self.viewModel.rootActive.wrappedValue = false
}) {
Image("LeftArrow").renderingMode(.original)
})
}
}
struct ViewDUI: View {
@SwiftUI.Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
let isDriver: Bool
let car: Binding<Car?>
let rootActive: Binding<Bool>
var body: some View {
GeometryReader { fullView in
ScrollView(.vertical, showsIndicators: false) {
VStack(alignment: .leading, spacing: 0) {
Text("").font(.regularParagraph).foregroundColor(Color.black).padding([.leading, .trailing], 20).padding(.top, 15)
CarDetailsView(car: self.car)
Spacer(minLength: 20)
if self.car.wrappedValue?.mot == true && self.car.wrappedValue?.taxed == true {
if self.isDriver {
Button(action: {
self.rootActive.wrappedValue = false
}) {
PrimaryButtonView(enabled: true, title: "Save")
}.padding(.bottom, 16).padding([.leading, .trailing], 20)
} else {
NavigationLink(destination: ViewE(rootActive: self.$viewModel.showB)) {
PrimaryButtonView(enabled: true, title: "Continue")
}.isDetailLink(false).padding(.bottom, 16).padding([.leading, .trailing], 20)
}
} else {
Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
PrimaryButtonView(enabled: true, title: "")
}.padding(.bottom, 16).padding([.leading, .trailing], 20)
}
}.frame(minHeight: fullView.size.height)
}
}
.navigationBarBackButtonHidden(true)
.navigationBarTitle("")
.navigationBarItems(leading: Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Image("LeftArrow").renderingMode(.original)
})
}
}
struct ViewEUI: View {
@SwiftUI.Environment(\.presentationMode) private var presentationMode: Binding<PresentationMode>
private let rootActive: Binding<Bool>
private let isDriver: Bool
@State private var showingScanner = false
@State private var scanHandler: LicenseScanHandler!
@State private var scanCompleted = false
var body: some View {
VStack(alignment: .leading, spacing: 0) {
Text("")
.font(.regularParagraph)
.padding(.top, 15)
.padding([.leading, .trailing], 20)
ZStack(alignment: .topLeading) {
VStack(alignment: .leading, spacing: 0) {
Image("sample")
.resizable()
.aspectRatio(contentMode: .fit)
.padding(20)
}
.overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.azure, lineWidth: 1))
.background(Color.white.edgesIgnoringSafeArea(.all))
.padding(.top, 12)
Text("")
.font(.tinyParagraph)
.foregroundColor(.azure)
.frame(width: 80, height: 24)
.background(Color.white.edgesIgnoringSafeArea(.all))
.cornerRadius(8)
.overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.azure, lineWidth: 1))
.padding(.leading, 20)
}
.padding([.leading, .trailing], 40)
.padding(.top, 16)
Spacer(minLength: 20)
Button(action: {
self.showingScanner = true
}) {
PrimaryButtonView(enabled: true, title: "Scan")
}.padding(.bottom, 16).padding([.leading, .trailing], 20)
.sheet(isPresented: $showingScanner) {
ScannerWrapper(handler: self.scanHandler)
}
NavigationLink(destination: InfoUI(), isActive: $scanCompleted) {
Text("")
}.isDetailLink(false)
}
.background(Color.offWhite.edgesIgnoringSafeArea(.all))
.navigationBarBackButtonHidden(true)
.navigationBarTitle("")
.navigationBarItems(leading: Button(action: {
self.presentationMode.wrappedValue.dismiss()
}) {
Image("LeftArrow").renderingMode(.original)
})
.onAppear {
self.scanHandler = LicenseScanHandler(delegate: self)
}
}
}