Replies: 2 comments 18 replies
-
Actually, with the 1.6 observation beta, I don't think this will be necessary, because you no longer need to use |
Beta Was this translation helpful? Give feedback.
-
I pulled TCA and was able to add the backport directly into the library. I imported @available(iOS 14, macOS 11, tvOS 14, watchOS 7, *)
extension NavigationStackBackport.NavigationStack {
/// Drives a navigation stack with a store.
///
/// See the dedicated article on <doc:Navigation> for more information on the library's navigation
/// tools, and in particular see <doc:StackBasedNavigation> for information on using this view.
public init<State, Action, Destination: View, R>(
path: Binding<Store<StackState<State>, StackAction<State, Action>>>,
root: () -> R,
@ViewBuilder destination: @escaping (Store<State, Action>) -> Destination
)
where
Data == StackState<State>.PathView,
Root == ModifiedContent<R, _NavigationDestinationViewModifierBackport<State, Action, Destination>>
{
self.init(
path: Binding(
get: { path.wrappedValue.currentState.path }, // <------- Errors 1 and 2
set: { pathView, transaction in
if pathView.count > path.wrappedValue.withState({ $0 }).count,
let component = pathView.last
{
path.transaction(transaction).wrappedValue.send(
.push(id: component.id, state: component.element) // <------- Errors 3 and 4
)
} else {
path.transaction(transaction).wrappedValue.send(
.popFrom(id: path.wrappedValue.withState { $0 }.ids[pathView.count])
)
}
}
)
) {
root()
.modifier(
_NavigationDestinationViewModifierBackport(store: path.wrappedValue, destination: destination)
)
}
}
}
@available(iOS 14, macOS 11, tvOS 14, watchOS 7, *)
public struct _NavigationDestinationViewModifierBackport<
State: ObservableState, Action, Destination: View
>:
ViewModifier
{
@SwiftUI.State var store: Store<StackState<State>, StackAction<State, Action>>
fileprivate let destination: (Store<State, Action>) -> Destination
public func body(content: Content) -> some View {
content
.environment(\.navigationDestinationType, State.self)
.backport.navigationDestination(for: StackState<State>.Component.self) { component in
var element = component.element
self
.destination(
self.store.scope(
id: self.store.id(state: \.[id:component.id], action: \.[id:component.id]),
state: ToState { // <------- Error 5
element = $0[id: component.id] ?? element
return element
},
action: { .element(id: component.id, action: $0) },
isInvalid: { !$0.ids.contains(component.id) }
)
)
.environment(\.navigationDestinationType, State.self)
}
}
} Of course, if I try to paste that into my own project I get several errors
|
Beta Was this translation helpful? Give feedback.
-
I would like to be able to use
NavigationStackStore
, but I have to support iOS 15. @Alex293 made a fork of TCA that integratesnavigation-stack-backport
and adds aNavigationStackStoreBP
. This seems to work really well, however it requires some private APIs from TCA. I would like to start a discussion to see if we can get the necessary APIs exposed to be able to paste something likeNavigationStackStore
into my project and get stack-based navigation working with TCA in iOS 15.I cloned TCA and opened up the SyncUps example app to find out what APIs would need to be made public for it to work.
navigation-stack-backport
NavigationStackStoreBP
Here are the things that I needed to make public in order to get into building order.
ViewStore
StackState._dictionary
areOrderedSetsDuplicates(_:_ :)
callAsFunction()
indent(by:)
invalidate(_)
runtimeWarn(_:category)
typeName(_)
It also uses
stackElementID
, but that is already marked as@_spi(Internals)
.Now, I don't think all of these necessarily need to be made public, but this is what I had to do for now.
For the sake of completion, here is the
NavigationStackStore
:Beta Was this translation helpful? Give feedback.
All reactions