Skip to content

Commit

Permalink
Remove AnyView dependency
Browse files Browse the repository at this point in the history
* Remove AnyView dependency
* Update version
  • Loading branch information
jimmy0251 authored Aug 31, 2022
1 parent 8a451c5 commit 34abdee
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 30 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Once you have your Swift package set up, adding UIPilot as a dependency is as ea

```swift
dependencies: [
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.2.1"))
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.0"))
]
```

Expand All @@ -47,7 +47,7 @@ dependencies: [
[CocoaPods][] is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate UIPilot into your Xcode project using CocoaPods, specify it in your Podfile:

target 'YourAppName' do
pod 'UIPilot', '~> 1.2.1'
pod 'UIPilot', '~> 1.3.0'
end

[CocoaPods]: https://cocoapods.org
Expand Down
53 changes: 28 additions & 25 deletions Sources/UIPilot/UIPilot.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public class UIPilot<T: Equatable>: ObservableObject {
paths.removeLast(numToPop)
}

func getView(_ paths: [UIPilotPath<T>], _ routeMap: RouteMap<T>, _ pathViews: [UIPilotPath<T>: PathView]) -> (PathView?, [UIPilotPath<T>: PathView]) {
func getView<Screen: View>(_ paths: [UIPilotPath<T>], _ routeMap: RouteMap<T, Screen>, _ pathViews: [UIPilotPath<T>: Screen]) -> (PathView<Screen>?, [UIPilotPath<T>: Screen]) {
return viewGenerator.generate(paths, routeMap, pathViews)
}
}
Expand All @@ -78,11 +78,11 @@ struct UIPilotPath<T: Equatable>: Equatable, Hashable {
}
}

struct PathView: View {
private let content: AnyView
@ObservedObject var state: PathViewState
struct PathView<Screen: View>: View {
private let content: Screen
@ObservedObject var state: PathViewState<Screen>

public init(_ content: AnyView, state: PathViewState) {
public init(_ content: Screen, state: PathViewState<Screen>) {
self.content = content
self.state = state
}
Expand All @@ -100,7 +100,7 @@ struct PathView: View {
}
}

class PathViewState: ObservableObject {
class PathViewState<Screen: View>: ObservableObject {
@Published
var isActive: Bool = false {
didSet {
Expand All @@ -111,15 +111,15 @@ class PathViewState: ObservableObject {
}

@Published
var next: PathView? {
var next: PathView<Screen>? {
didSet {
isActive = next != nil
}
}

var onPop: () -> Void

init(next: PathView? = nil, onPop: @escaping () -> Void = {}) {
init(next: PathView<Screen>? = nil, onPop: @escaping () -> Void = {}) {
self.next = next
self.onPop = onPop
}
Expand All @@ -129,20 +129,22 @@ class PathViewGenerator<T: Equatable> {

var onPop: ((UIPilotPath<T>) -> Void)?

func generate(_ paths: [UIPilotPath<T>], _ routeMap: RouteMap<T>, _ pathViews: [UIPilotPath<T>: PathView]) -> (PathView?, [UIPilotPath<T>: PathView]) {
func generate<Screen: View>(
_ paths: [UIPilotPath<T>],
@ViewBuilder _ routeMap: RouteMap<T, Screen>,
_ pathViews: [UIPilotPath<T>: Screen]) -> (PathView<Screen>?,
[UIPilotPath<T>: Screen]) {
var pathViews = recycleViews(paths, pathViews: pathViews)

var current: PathView?
var current: PathView<Screen>?
for path in paths.reversed() {
var content = pathViews[path]
let view = pathViews[path] ?? routeMap(path.route)
pathViews[path] = view

let content = PathView(view, state: PathViewState())

if content == nil {
pathViews[path] = PathView(routeMap(path.route), state: PathViewState())
content = pathViews[path]
}

content?.state.next = current
content?.state.onPop = current == nil ? {} : { [weak self] in
content.state.next = current
content.state.onPop = current == nil ? {} : { [weak self] in
if let self = self {
self.onPop?(path)
}
Expand All @@ -152,7 +154,7 @@ class PathViewGenerator<T: Equatable> {
return (current, pathViews)
}

private func recycleViews(_ paths: [UIPilotPath<T>], pathViews: [UIPilotPath<T>: PathView]) -> [UIPilotPath<T>: PathView] {
private func recycleViews<Screen: View>(_ paths: [UIPilotPath<T>], pathViews: [UIPilotPath<T>: Screen]) -> [UIPilotPath<T>: Screen] {
var pathViews = pathViews
for key in pathViews.keys {
if !paths.contains(key) {
Expand All @@ -163,21 +165,22 @@ class PathViewGenerator<T: Equatable> {
}
}

public typealias RouteMap<T> = (T) -> AnyView
public typealias RouteMap<T, Screen> = (T) -> Screen

public struct UIPilotHost<T: Equatable>: View {
public struct UIPilotHost<T: Equatable, Screen: View>: View {

@ObservedObject
private var pilot: UIPilot<T>

private let routeMap: RouteMap<T>
@ViewBuilder
let routeMap: RouteMap<T, Screen>

@State
var pathViews = [UIPilotPath<T>: PathView]()
var pathViews = [UIPilotPath<T>: Screen]()
@State
var content: PathView?
var content: PathView<Screen>?

public init(_ pilot: UIPilot<T>, _ routeMap: @escaping RouteMap<T>) {
public init(_ pilot: UIPilot<T>, @ViewBuilder _ routeMap: @escaping RouteMap<T, Screen>) {
self.pilot = pilot
self.routeMap = routeMap
}
Expand Down
2 changes: 1 addition & 1 deletion UIPilot.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "UIPilot"
s.version = "1.2.1"
s.version = "1.3.0"
s.summary = "The missing type-safe, SwiftUI navigation library."

s.description = <<-DESC
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ Once you have your Swift package set up, adding UIPilot as a dependency is as ea

```swift
dependencies: [
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.2.1"))
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.0"))
]
```

Expand All @@ -332,7 +332,7 @@ dependencies: [
[CocoaPods][] is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate UIPilot into your Xcode project using CocoaPods, specify it in your Podfile:

target 'YourAppName' do
pod 'UIPilot', '~> 1.2.1'
pod 'UIPilot', '~> 1.3.0'
end

[CocoaPods]: https://cocoapods.org
Expand Down

0 comments on commit 34abdee

Please sign in to comment.