Files
swift-composable-architectu…/Sources/ComposableArchitecture/UIKit/NavigationStackControllerUIKit.swift
Stephen Celis a7e2e73f83 Swift 6: Key path sendability (#3282)
* `@preconcurrency @MainActor` isolation of `Store`

* Remove unneeded `@MainActor`s

* Remove thread checking code

* Remove unneeded `@MainActor`s

* Swift 5.10 compatibility fixes

* wip

* More 5.10 fixes

* wip

* fixes

* wip

* wip

* up the timeout

* wip

* Fixes

* wip

* wip

* wip

* wip

* wip

* Fix binding action sendability

* Address more binding action sendability

* more bindable action sendability

* more bindable action warnings

* fix

---------

Co-authored-by: Brandon Williams <mbrandonw@hey.com>
2024-08-29 13:46:39 -07:00

73 lines
2.8 KiB
Swift

#if canImport(UIKit) && !os(watchOS)
import UIKit
extension NavigationStackController {
/// Drives a navigation stack controller 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.
///
/// - Parameters:
/// - navigationBarClass: Specify the custom `UINavigationBar` subclass you want to use, or
/// specify `nil` to use the standard `UINavigationBar` class.
/// - toolbarClass: Specify the custom `UIToolbar` subclass you want to use, or specify `nil`
/// to use the standard `UIToolbar` class.
/// - path: A binding to a store of stack state.
/// - root: A root view controller.
/// - destination: A function to create a `UIViewController` from a store.
/// - fileID: The source `#fileID` associated with the controller.
/// - filePath: The source `#filePath` associated with the controller.
/// - line: The source `#line` associated with the controller.
/// - column: The source `#column` associated with the controller.
public convenience init<State, Action>(
navigationBarClass: AnyClass? = nil,
toolbarClass: AnyClass? = nil,
path: UIBinding<Store<StackState<State>, StackAction<State, Action>>>,
root: () -> UIViewController,
destination: @escaping (Store<State, Action>) -> UIViewController,
fileID: StaticString = #fileID,
filePath: StaticString = #filePath,
line: UInt = #line,
column: UInt = #column
) {
self.init(
navigationBarClass: navigationBarClass,
toolbarClass: toolbarClass,
path: path[
fileID: _HashableStaticString(rawValue: fileID),
filePath: _HashableStaticString(rawValue: filePath),
line: line,
column: column
],
root: root
)
navigationDestination(for: StackState<State>.Component.self) { component in
var element = component.element
return destination(
path.wrappedValue.scope(
id: path.wrappedValue.id(
state:
\.[
id: component.id,
fileID: _HashableStaticString(
rawValue: fileID),
filePath: _HashableStaticString(
rawValue: filePath), line: line, column: column
],
action: \.[id: component.id]
),
state: ToState {
element = $0[id: component.id] ?? element
return element
},
action: { .element(id: component.id, action: $0) },
isInvalid: { !$0.ids.contains(component.id) }
)
)
}
}
}
#endif