Skip to content

Commit

Permalink
Merge pull request #8 from kvyatkovskys/feature/v_0.1.3
Browse files Browse the repository at this point in the history
use the generic base class
  • Loading branch information
kvyatkovskys authored Feb 17, 2024
2 parents a6f586c + 4c68e21 commit 1735193
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 143 deletions.
2 changes: 1 addition & 1 deletion KVKFlowCoordinators.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |spec|

spec.name = "KVKFlowCoordinators"
spec.version = "0.1.2"
spec.version = "0.1.3"
spec.summary = "SwiftUI flow coordinators"
spec.description = <<-DESC
SwiftUI flow coordinator to control navigation in your App.
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[![SwiftPM compatible](https://img.shields.io/badge/SwiftPM-compatible-orange.svg)](https://swiftpackageindex.com/kvyatkovskys/KVKFlowCoordinators)
[![License](https://img.shields.io/cocoapods/l/KVKCalendar.svg?style=flat)](https://cocoapods.org/pods/KVKFlowCoordinators)


# KVKFlowCoordinators
SwiftUI flow coordinator to control navigation in your App.

Expand Down Expand Up @@ -34,12 +33,14 @@ pod 'KVKFlowCoordinators'
## Usage for SwiftUI
- Import `KVKFlowCoordinators`.
- Create an entities with type of navigation (for ex. `enum SheetType: FlowTypeProtocol`).
- Create a coordinator that inherits from the`FlowCoordinator` base class if you want to use `.sheet`, `.navigationDestination`, `.fullScreenCover`. Or use a specific coordinator class `SheetCoordinator, LinkCoordinator, CoverCoordinator, SheetAndLinkCoordinator, SheetAndCoverCoordinator, LinkAndCoverCoordinator`.
- Create a coordinator that inherits from the`FlowCoordinator` base class if you want to use `.sheet`, `.navigationDestination`, `.fullScreenCover`.
- Or use a specific coordinator class `SheetCoordinator, LinkCoordinator, CoverCoordinator, SheetAndLinkCoordinator, SheetAndCoverCoordinator, LinkAndCoverCoordinator`.
- Create a `ViewModel` if you need.
- Create a `CoordinatorView` with the created coordinator.


To work with navigationLink use `.navigationDestination(for: NavigationLinkType.self)`. The `.navigationDestination(item: $item)` doesn't work.
To work with navigationLink use `.navigationDestination(for: NavigationLinkType.self)`.
_`.navigationDestination(item: $item)` doesn't work._


```swift
Expand Down Expand Up @@ -101,10 +102,6 @@ struct ContentView: View {

var body: some View {
VStack(spacing: 30) {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
Button("Open Sheet") {
vm.openSheetFirst(autoClose: false)
}
Expand All @@ -128,10 +125,13 @@ struct ContentView: View {
}
```

## Demo
https://github.com/kvyatkovskys/KVKFlowCoordinators/assets/8233076/4f4bd26b-8103-41a4-94ff-a9e25249bd02

## Author

[Sergei Kviatkovskii](https://github.com/kvyatkovskys)

## License

KVKFlowCoordinators is available under the [MIT license](https://github.com/kvyatkovskys/KVKFlowCoordinators/blob/master/LICENSE.md)
KVKFlowCoordinators is available under the [MIT license](https://github.com/kvyatkovskys/KVKFlowCoordinators/blob/master/LICENSE)
168 changes: 34 additions & 134 deletions Sources/KVKFlowCoordinators/KVKFlowCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public protocol FlowProtocol: ObservableObject {

func popToRoot()
func popView()
func pushTo(_ link: any FlowTypeProtocol)
func pushTo(_ link: L)
}

extension FlowProtocol {
Expand All @@ -38,7 +38,7 @@ extension FlowProtocol {
}

@available(swift, obsoleted: 0.1.1, renamed: "pushTo")
public func pushToLink(_ link: any FlowTypeProtocol) {
public func pushToLink<L: FlowTypeProtocol>(_ link: L) {
pushTo(link)
}

Expand All @@ -58,7 +58,7 @@ extension FlowProtocol {
}
}

public func pushTo(_ link: any FlowTypeProtocol) {
public func pushTo<L: FlowTypeProtocol>(_ link: L) {
if let parentFlowCoordinator {
parentFlowCoordinator.path.append(link)
} else {
Expand All @@ -73,21 +73,17 @@ extension FlowProtocol {
public func dismissCover() {
coverType = nil
}
}

public protocol FlowTypeProtocol: Identifiable, Hashable {}

/// stab for child coordinators
/// - class Coordinator: FlowCoordinator<SheetType, **FlowEmptyType**, CoverType>
public struct FlowEmptyType: FlowTypeProtocol {
public var id: Int {
0

// MARK: Internal-
func removeObservers() {
cancellable.removeAll()
}
}

open class FlowCoordinator<Sheet: FlowTypeProtocol, Link: FlowTypeProtocol, Cover: FlowTypeProtocol>: FlowProtocol {
open class FlowBaseCoordinator<Sheet: FlowTypeProtocol, Link: FlowTypeProtocol, Cover: FlowTypeProtocol>: FlowProtocol {

public typealias S = Sheet
public typealias N = Link
public typealias L = Link
public typealias C = Cover

@Published public var sheetType: Sheet?
Expand All @@ -108,133 +104,37 @@ open class FlowCoordinator<Sheet: FlowTypeProtocol, Link: FlowTypeProtocol, Cove
}

deinit {
cancellable.removeAll()
removeObservers()
}
}

open class SheetCoordinator<Sheet: FlowTypeProtocol>: FlowProtocol {
public typealias S = Sheet
public typealias N = FlowEmptyType
public typealias C = FlowEmptyType

@Published public var sheetType: Sheet?
@Published public var linkType: FlowEmptyType?
@Published public var coverType: FlowEmptyType?
@Published public var path = NavigationPath()
public var cancellable = Set<AnyCancellable>()
public var parentFlowCoordinator: (any FlowProtocol)?

public init(parentFlowCoordinator: (any FlowProtocol)? = nil) {
self.parentFlowCoordinator = parentFlowCoordinator
}
}
public protocol FlowTypeProtocol: Identifiable, Hashable {}

open class LinkCoordinator<Link: FlowTypeProtocol>: FlowProtocol {
public typealias S = FlowEmptyType
public typealias N = Link
public typealias C = FlowEmptyType

@Published public var sheetType: FlowEmptyType?
@Published public var linkType: Link?
@Published public var coverType: FlowEmptyType?
@Published public var path = NavigationPath()
public var cancellable = Set<AnyCancellable>()
public var parentFlowCoordinator: (any FlowProtocol)?

public init(parentFlowCoordinator: (any FlowProtocol)? = nil) {
self.parentFlowCoordinator = parentFlowCoordinator
$linkType
.compactMap { $0 }
.sink { [weak self] link in
self?.pushTo(link)
}
.store(in: &cancellable)
}

deinit {
cancellable.removeAll()
/// stab for child coordinators
/// - class Coordinator: FlowCoordinator<SheetType, **FlowEmptyType**, CoverType>
public enum FlowEmptyType: FlowTypeProtocol {
public var id: Int {
0
}
}

open class CoverCoordinator<Cover: FlowTypeProtocol>: FlowProtocol {
public typealias S = FlowEmptyType
public typealias N = FlowEmptyType
public typealias C = Cover

@Published public var sheetType: FlowEmptyType?
@Published public var linkType: FlowEmptyType?
@Published public var coverType: Cover?
@Published public var path = NavigationPath()
public var cancellable = Set<AnyCancellable>()
public var parentFlowCoordinator: (any FlowProtocol)?

public init(parentFlowCoordinator: (any FlowProtocol)? = nil) {
self.parentFlowCoordinator = parentFlowCoordinator
}
}
/// To contol all navigation types
open class FlowCoordinator<Sheet: FlowTypeProtocol, Link: FlowTypeProtocol, Cover: FlowTypeProtocol>: FlowBaseCoordinator<Sheet, Link, Cover> {}

open class SheetAndLinkCoordinator<Sheet: FlowTypeProtocol, Link: FlowTypeProtocol>: FlowProtocol {
public typealias S = Sheet
public typealias N = Link
public typealias C = FlowEmptyType

@Published public var sheetType: Sheet?
@Published public var linkType: Link?
@Published public var coverType: FlowEmptyType?
@Published public var path = NavigationPath()
public var cancellable = Set<AnyCancellable>()
public var parentFlowCoordinator: (any FlowProtocol)?

public init(parentFlowCoordinator: (any FlowProtocol)? = nil) {
self.parentFlowCoordinator = parentFlowCoordinator
$linkType
.compactMap { $0 }
.sink { [weak self] link in
self?.pushTo(link)
}
.store(in: &cancellable)
}

deinit {
cancellable.removeAll()
}
}
/// To contol sheet navigation
open class SheetCoordinator<Sheet: FlowTypeProtocol>: FlowBaseCoordinator<Sheet, FlowEmptyType, FlowEmptyType> {}

open class SheetAndCoverCoordinator<Sheet: FlowTypeProtocol, Cover: FlowTypeProtocol>: FlowProtocol {
public typealias S = Sheet
public typealias N = FlowEmptyType
public typealias C = Cover

@Published public var sheetType: Sheet?
@Published public var linkType: FlowEmptyType?
@Published public var coverType: Cover?
@Published public var path = NavigationPath()
public var cancellable = Set<AnyCancellable>()
public var parentFlowCoordinator: (any FlowProtocol)?
}
/// To contol link navigation
open class LinkCoordinator<Link: FlowTypeProtocol>: FlowBaseCoordinator<FlowEmptyType, Link, FlowEmptyType> {}

open class LinkAndCoverCoordinator<Link: FlowTypeProtocol, Cover: FlowTypeProtocol>: FlowProtocol {
public typealias S = FlowEmptyType
public typealias N = Link
public typealias C = Cover

@Published public var sheetType: FlowEmptyType?
@Published public var linkType: Link?
@Published public var coverType: Cover?
@Published public var path = NavigationPath()
public var cancellable = Set<AnyCancellable>()
public var parentFlowCoordinator: (any FlowProtocol)?

public init() {
$linkType
.compactMap { $0 }
.sink { [weak self] link in
self?.pushTo(link)
}
.store(in: &cancellable)
}

deinit {
cancellable.removeAll()
}
}
/// To contol cover navigation
open class CoverCoordinator<Cover: FlowTypeProtocol>: FlowBaseCoordinator<FlowEmptyType, FlowEmptyType, Cover> {}

/// To contol sheet and link navigation types
open class SheetAndLinkCoordinator<Sheet: FlowTypeProtocol, Link: FlowTypeProtocol>: FlowBaseCoordinator<Sheet, Link, FlowEmptyType> {}

/// To contol shent and cover navigation
open class SheetAndCoverCoordinator<Sheet: FlowTypeProtocol, Cover: FlowTypeProtocol>: FlowBaseCoordinator<Sheet, FlowEmptyType, Cover> {}

/// To contol link and cover navigation
open class LinkAndCoverCoordinator<Link: FlowTypeProtocol, Cover: FlowTypeProtocol>: FlowBaseCoordinator<FlowEmptyType, Link, Cover> {}

0 comments on commit 1735193

Please sign in to comment.