Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions Sources/FuturedArchitecture/Architecture/Coordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,18 @@ extension Coordinator {
}

/// `TabCoordinator` provides additional requirements for the use with ``SwiftUI.TabView``.
/// This *coordinator* is ment to have ``TabViewFlow`` as the Root view.
/// This *coordinator* is meant to have ``TabViewFlow`` (or ``TabContentFlow`` on iOS 18+) as the Root view.
/// - Experiment: This API is in preview and subject to change.
/// - Todo: ``SwiftUI.TabView`` requires internal state, which is forbidden as per
/// documentation of ``Coordinator.rootView(with:)``. Also, the API introduces `Tab` type
/// which is essentially duplication of `Destination`. Consider, how the API limits the use of tabs.
public protocol TabCoordinator: Coordinator {
associatedtype Tab: Hashable
/// The `Hashable` value used to identify the currently selected tab. Matches the `value:`
/// parameter of ``SwiftUI.Tab`` when using ``TabContentFlow``.
associatedtype TabValue: Hashable

var selectedTab: Tab { get set }
var selectedTab: TabValue { get set }
}

/// `NavigationStackCoordinator` provides additional requirements for use with ``SwiftUI.NavigationStack``.
/// This *coordinator* is ment have ``NavigationStackFlow`` as the Root view.
/// This *coordinator* is meant to have ``NavigationStackFlow`` as the Root view.
///
/// - ToDo: Create a template for this coordinator.
public protocol NavigationStackCoordinator: Coordinator {
Expand Down
10 changes: 5 additions & 5 deletions Sources/FuturedArchitecture/Architecture/TabViewFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ public struct TabViewFlow<Coordinator: TabCoordinator, Content: View>: View {
/// Usage:
/// ```swift
/// TabContentFlow(coordinator: instance) {
/// Tab("Home", systemImage: "house", value: Tab.home) { ... }
/// Tab(value: Tab.search, role: .search) { ... }
/// Tab("Home", systemImage: "house", value: AppTab.home) { ... }
/// Tab(value: AppTab.search, role: .search) { ... }
/// }
/// ```
/// - Experiment: This API is in preview and subject to change.
@available(iOS 18.0, macOS 15.0, tvOS 18.0, watchOS 11.0, *)
public struct TabContentFlow<Coordinator: TabCoordinator, Content: TabContent<Coordinator.Tab>>: View {
public struct TabContentFlow<Coordinator: TabCoordinator, Content: TabContent<Coordinator.TabValue>>: View {
@State private var coordinator: Coordinator
@TabContentBuilder<Coordinator.Tab> private let content: () -> Content
@TabContentBuilder<Coordinator.TabValue> private let content: () -> Content

/// - Parameters:
/// - coordinator: The instance of the coordinator used as the model and retained as ``SwiftUI.State``
/// - content: The definition of tabs using the ``SwiftUI.Tab`` API.
public init(coordinator: Coordinator, @TabContentBuilder<Coordinator.Tab> content: @MainActor @escaping () -> Content) {
public init(coordinator: Coordinator, @TabContentBuilder<Coordinator.TabValue> content: @MainActor @escaping () -> Content) {
self._coordinator = State(wrappedValue: coordinator)
self.content = content
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,31 @@ import SwiftUI

@Observable
final class ___VARIABLE_tabCoordinatorIdentifier___TabCoordinator: @MainActor TabCoordinator {
nonisolated enum Tab {
nonisolated enum AppTab {
case firstTab
case secondTab
}

private let container: Container

var selectedTab: Tab
var selectedTab: AppTab
var modalCover: ModalCoverModel<Destination>?

init(container: Container, selectedTab: Tab) {
init(container: Container, selectedTab: AppTab) {
self.container = container
self.selectedTab = selectedTab
}

@ViewBuilder
static func rootView(with instance: ___VARIABLE_tabCoordinatorIdentifier___TabCoordinator) -> some View {
TabViewFlow(coordinator: instance) {
Text("First Tab")
.tabItem {
Text("First")
}
.tag(Tab.firstTab)

Text("Second Tab")
.tabItem {
Text("Second")
}
.tag(Tab.secondTab)
TabContentFlow(coordinator: instance) {
Tab("First", systemImage: "1.circle", value: AppTab.firstTab) {
Text("First Tab")
}

Tab("Second", systemImage: "2.circle", value: AppTab.secondTab) {
Text("Second Tab")
}
}
}

Expand Down