FlowStacks
FlowStacks copied to clipboard
SwiftUI's native dismiss environment value does not work from fullscreen modal with navigation
There is a bug where attempting to use SwiftUI's native dismiss environment value does not work from a fullscreen modal presented with navigation: foo.presentCover(Screen.modalView, withNavigation: true)
. This bug is present in both the 0.8.1 and 0.8.2 versions (I haven't checked any other versions). Workaround is to use FlowPathNavigator
or a reference to the FlowPath
associated with the FlowStack
because FlowStacks dismiss APIs still work as expected. See code example below:
import Foundation
import FlowStacks
import SwiftUI
public enum Screen {
case modalView
}
extension Screen: Identifiable, Hashable {
public var id: String {
return String(reflecting: self)
}
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public static func == (lhs: Screen, rhs: Screen) -> Bool {
lhs.id == rhs.id
}
}
struct ScreenViewBuilder {
static func view(for screen: Screen) -> some View {
switch screen {
case .modalView:
return ModalView()
}
}
}
struct ContentView: View {
@State var path = FlowPath()
var body: some View {
FlowStack($path, withNavigation: true) {
makeRootView()
.flowDestination(for: Screen.self) { screen in
ScreenViewBuilder.view(for: screen)
}
}
}
@ViewBuilder private func makeRootView() -> some View {
Button("Present ModalView with navigation") {
path.presentCover(Screen.modalView, withNavigation: true)
}
}
}
struct ModalView: View {
@Environment(\.dismiss) private var dismiss
@EnvironmentObject var navigator: FlowPathNavigator
var body: some View {
Text("Modal View")
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("Native Dismiss") {
dismiss() // does not work
}
}
ToolbarItem(placement: .topBarTrailing) {
Button("FlowStacks Dismiss") {
navigator.dismiss() // works
// navigator.goBack() // works
}
}
}
}
}