diff --git a/Sources/FuturedArchitecture/Architecture/Coordinator.swift b/Sources/FuturedArchitecture/Architecture/Coordinator.swift index dbfda47..078472c 100644 --- a/Sources/FuturedArchitecture/Architecture/Coordinator.swift +++ b/Sources/FuturedArchitecture/Architecture/Coordinator.swift @@ -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 { diff --git a/Sources/FuturedArchitecture/Architecture/TabViewFlow.swift b/Sources/FuturedArchitecture/Architecture/TabViewFlow.swift index 92c9b63..6a1c7e0 100644 --- a/Sources/FuturedArchitecture/Architecture/TabViewFlow.swift +++ b/Sources/FuturedArchitecture/Architecture/TabViewFlow.swift @@ -42,20 +42,20 @@ public struct TabViewFlow: 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>: View { +public struct TabContentFlow>: View { @State private var coordinator: Coordinator - @TabContentBuilder private let content: () -> Content + @TabContentBuilder 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 content: @MainActor @escaping () -> Content) { + public init(coordinator: Coordinator, @TabContentBuilder content: @MainActor @escaping () -> Content) { self._coordinator = State(wrappedValue: coordinator) self.content = content } diff --git a/Templates/Tab Coordinator.xctemplate/___VARIABLE_tabCoordinatorIdentifier___TabCoordinator.swift b/Templates/Tab Coordinator.xctemplate/___VARIABLE_tabCoordinatorIdentifier___TabCoordinator.swift index d95a0ab..c5b4b45 100644 --- a/Templates/Tab Coordinator.xctemplate/___VARIABLE_tabCoordinatorIdentifier___TabCoordinator.swift +++ b/Templates/Tab Coordinator.xctemplate/___VARIABLE_tabCoordinatorIdentifier___TabCoordinator.swift @@ -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? - 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") + } } }