Using the new navigationDestination and NavigationPath functions previously on iOS 16 everything has been working fine using a custom back button, which calls path.removeLast().
However, if we try this on iOS 17, the screen being removed flashes white.
You can try this code as an example (NOTE THE WHITE FLASH ON REMOVE LAST):
struct DetailView: View {
@Binding var path: NavigationPath
var body: some View {
ZStack {
Color.black
VStack(alignment: .center) {
Spacer()
Button(action: {
path.removeLast()
}, label: {
Text("BACK")
})
Spacer()
}
}
}
}
struct ParentView: View {
@State var path: NavigationPath = .init()
var body: some View {
NavigationStack(path: $path) {
ZStack {
Color.red
VStack(alignment: .center) {
Spacer()
Button(action: {
path.append("TEST")
}, label: {
Text("FORWARD")
})
Spacer()
}
}
.navigationDestination(for: String.self) { _ in
DetailView(path: $path)
}
}
}
}
Any work arounds? Suggestions?
Post
Replies
Boosts
Views
Activity
The following code works:
struct SelectBatteryChemistryView: View {
@ObservedObject var model: SelectBatteryChemistryViewModel = .init()
@Environment(\.presentationMode) private var presentationMode
var body: some View {
VStack {
Spacer()
TitleText("BATTERY MODE")
SimpleModeSelectorView(
selected: $model.batteryChemistry
)
.pickerStyle(.inline)
.frame(minHeight: 300)
PrimaryTitleButton(title: "SELECT") {
if model.batteryChemistry == .user {
model.customChemistryFlow = true
} else {
model.confirmBatterySettings()
}
}
NavigationLink(
destination: CustomBatteryChemistryView(),
isActive: $model.customChemistryFlow
) { EmptyView() }
.isDetailLink(false)
}
.onReceive(model.$batterySettingsConfirmed) { batterySettingsConfirmed in
if batterySettingsConfirmed {
//dismiss()
}
}
.onAppear() {
model.customChemistryFlow = false
}
}
}
The following code causes an infinite loop in the CustomBatteryChemistryView() initialiser.
struct SelectBatteryChemistryView: View {
@ObservedObject var model: SelectBatteryChemistryViewModel = .init()
@Environment(\.dismiss) private var dismiss
var body: some View {
VStack {
Spacer()
TitleText("BATTERY MODE")
SimpleModeSelectorView(
selected: $model.batteryChemistry
)
.pickerStyle(.inline)
.frame(minHeight: 300)
PrimaryTitleButton(title: "SELECT") {
if model.batteryChemistry == .user {
model.customChemistryFlow = true
} else {
model.confirmBatterySettings()
}
}
NavigationLink(
destination: CustomBatteryChemistryView(),
isActive: $model.customChemistryFlow
) { EmptyView() }
.isDetailLink(false)
}
.onReceive(model.$batterySettingsConfirmed) { batterySettingsConfirmed in
if batterySettingsConfirmed {
//dismiss()
}
}
.onAppear() {
model.customChemistryFlow = false
}
}
}
Adding the @Environment(.dismiss) object prevents the use of a navigation link. The program sits there with the stack infinitely calling the getter for the NavigationLink.
It looks like an infinite loop on the accessor due to some strangeness related to the magic of the Dismiss environment object.
How do we pass this on to the Dev team at Apple?
Using the new navigationDestination and NavigationPath functions previously on iOS 16 everything has been working fine using a custom back button, which calls path.removeLast().
However, if we try this on iOS 17 BETA 5, the screen being removed flashes white.
Also, how can I raise this as a bug with Apple, so they can fix it before the release of iOS 17.
You can try this code as an example (NOTE THE WHITE FLASH ON REMOVE LAST):
struct DetailView: View {
@Binding var path: NavigationPath
var body: some View {
ZStack {
Color.black
VStack(alignment: .center) {
Spacer()
Button(action: {
path.removeLast()
}, label: {
Text("BACK")
})
Spacer()
}
}
}
}
struct ParentView: View {
@State var path: NavigationPath = .init()
var body: some View {
NavigationStack(path: $path) {
ZStack {
Color.red
VStack(alignment: .center) {
Spacer()
Button(action: {
path.append("TEST")
}, label: {
Text("FORWARD")
})
Spacer()
}
}
.navigationDestination(for: String.self) { _ in
DetailView(path: $path)
}
}
}
}