import ComposableArchitecture import ComposablePresentation import SwiftUI struct NavigationDestinationExample: ReducerProtocol { struct State { var detail: Detail.State? } enum Action { case didTapDetailButton case didDismissDetail case detail(Detail.Action) } var body: some ReducerProtocol { Reduce { state, action in switch action { case .didTapDetailButton: state.detail = Detail.State() return .none case .didDismissDetail, .detail(.didTapDismissButton): state.detail = nil return .none case .detail(_): return .none } } .presenting( state: .keyPath(\.detail), id: .notNil(), action: /Action.detail, presented: Detail.init ) } // MARK: - Child Reducers struct Detail: ReducerProtocol { struct State { var timer = TimerExample.State() } enum Action { case didTapDismissButton case timer(TimerExample.Action) } var body: some ReducerProtocol { Scope(state: \.timer, action: /Action.timer) { TimerExample() } } } } struct NavigationDestinationExampleView: View { let store: StoreOf var body: some View { _NavigationStack { Button { ViewStore(store.stateless).send(.didTapDetailButton) } label: { Text("Detail").padding() } ._navigationDestination( store.scope( state: \.detail, action: NavigationDestinationExample.Action.detail ), onDismiss: { ViewStore(store.stateless).send(.didDismissDetail) }, destination: DetailView.init(store:) ) } .navigationTitle("NavigationDestinationExample") } // MARK: - Child Views struct DetailView: View { let store: StoreOf var body: some View { VStack { TimerExampleView(store: store.scope( state: \.timer, action: NavigationDestinationExample.Detail.Action.timer )) Button(action: { ViewStore(store.stateless).send(.didTapDismissButton) }) { Text("Dismiss").padding() } } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color(.secondarySystemBackground).ignoresSafeArea()) .navigationTitle("Detail") } } } struct NavigationDestinationExample_Previews: PreviewProvider { static var previews: some View { NavigationDestinationExampleView(store: Store( initialState: NavigationDestinationExample.State(), reducer: NavigationDestinationExample() )) } }