Skip to content

Commit 34abdee

Browse files
authored
Remove AnyView dependency
* Remove AnyView dependency * Update version
1 parent 8a451c5 commit 34abdee

File tree

4 files changed

+33
-30
lines changed

4 files changed

+33
-30
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Once you have your Swift package set up, adding UIPilot as a dependency is as ea
3838

3939
```swift
4040
dependencies: [
41-
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.2.1"))
41+
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.0"))
4242
]
4343
```
4444

@@ -47,7 +47,7 @@ dependencies: [
4747
[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:
4848

4949
target 'YourAppName' do
50-
pod 'UIPilot', '~> 1.2.1'
50+
pod 'UIPilot', '~> 1.3.0'
5151
end
5252

5353
[CocoaPods]: https://cocoapods.org

Sources/UIPilot/UIPilot.swift

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class UIPilot<T: Equatable>: ObservableObject {
6060
paths.removeLast(numToPop)
6161
}
6262

63-
func getView(_ paths: [UIPilotPath<T>], _ routeMap: RouteMap<T>, _ pathViews: [UIPilotPath<T>: PathView]) -> (PathView?, [UIPilotPath<T>: PathView]) {
63+
func getView<Screen: View>(_ paths: [UIPilotPath<T>], _ routeMap: RouteMap<T, Screen>, _ pathViews: [UIPilotPath<T>: Screen]) -> (PathView<Screen>?, [UIPilotPath<T>: Screen]) {
6464
return viewGenerator.generate(paths, routeMap, pathViews)
6565
}
6666
}
@@ -78,11 +78,11 @@ struct UIPilotPath<T: Equatable>: Equatable, Hashable {
7878
}
7979
}
8080

81-
struct PathView: View {
82-
private let content: AnyView
83-
@ObservedObject var state: PathViewState
81+
struct PathView<Screen: View>: View {
82+
private let content: Screen
83+
@ObservedObject var state: PathViewState<Screen>
8484

85-
public init(_ content: AnyView, state: PathViewState) {
85+
public init(_ content: Screen, state: PathViewState<Screen>) {
8686
self.content = content
8787
self.state = state
8888
}
@@ -100,7 +100,7 @@ struct PathView: View {
100100
}
101101
}
102102

103-
class PathViewState: ObservableObject {
103+
class PathViewState<Screen: View>: ObservableObject {
104104
@Published
105105
var isActive: Bool = false {
106106
didSet {
@@ -111,15 +111,15 @@ class PathViewState: ObservableObject {
111111
}
112112

113113
@Published
114-
var next: PathView? {
114+
var next: PathView<Screen>? {
115115
didSet {
116116
isActive = next != nil
117117
}
118118
}
119119

120120
var onPop: () -> Void
121121

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

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

132-
func generate(_ paths: [UIPilotPath<T>], _ routeMap: RouteMap<T>, _ pathViews: [UIPilotPath<T>: PathView]) -> (PathView?, [UIPilotPath<T>: PathView]) {
132+
func generate<Screen: View>(
133+
_ paths: [UIPilotPath<T>],
134+
@ViewBuilder _ routeMap: RouteMap<T, Screen>,
135+
_ pathViews: [UIPilotPath<T>: Screen]) -> (PathView<Screen>?,
136+
[UIPilotPath<T>: Screen]) {
133137
var pathViews = recycleViews(paths, pathViews: pathViews)
134138

135-
var current: PathView?
139+
var current: PathView<Screen>?
136140
for path in paths.reversed() {
137-
var content = pathViews[path]
141+
let view = pathViews[path] ?? routeMap(path.route)
142+
pathViews[path] = view
143+
144+
let content = PathView(view, state: PathViewState())
138145

139-
if content == nil {
140-
pathViews[path] = PathView(routeMap(path.route), state: PathViewState())
141-
content = pathViews[path]
142-
}
143-
144-
content?.state.next = current
145-
content?.state.onPop = current == nil ? {} : { [weak self] in
146+
content.state.next = current
147+
content.state.onPop = current == nil ? {} : { [weak self] in
146148
if let self = self {
147149
self.onPop?(path)
148150
}
@@ -152,7 +154,7 @@ class PathViewGenerator<T: Equatable> {
152154
return (current, pathViews)
153155
}
154156

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

166-
public typealias RouteMap<T> = (T) -> AnyView
168+
public typealias RouteMap<T, Screen> = (T) -> Screen
167169

168-
public struct UIPilotHost<T: Equatable>: View {
170+
public struct UIPilotHost<T: Equatable, Screen: View>: View {
169171

170172
@ObservedObject
171173
private var pilot: UIPilot<T>
172174

173-
private let routeMap: RouteMap<T>
175+
@ViewBuilder
176+
let routeMap: RouteMap<T, Screen>
174177

175178
@State
176-
var pathViews = [UIPilotPath<T>: PathView]()
179+
var pathViews = [UIPilotPath<T>: Screen]()
177180
@State
178-
var content: PathView?
181+
var content: PathView<Screen>?
179182

180-
public init(_ pilot: UIPilot<T>, _ routeMap: @escaping RouteMap<T>) {
183+
public init(_ pilot: UIPilot<T>, @ViewBuilder _ routeMap: @escaping RouteMap<T, Screen>) {
181184
self.pilot = pilot
182185
self.routeMap = routeMap
183186
}

UIPilot.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "UIPilot"
3-
s.version = "1.2.1"
3+
s.version = "1.3.0"
44
s.summary = "The missing type-safe, SwiftUI navigation library."
55

66
s.description = <<-DESC

docs/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ Once you have your Swift package set up, adding UIPilot as a dependency is as ea
323323

324324
```swift
325325
dependencies: [
326-
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.2.1"))
326+
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.0"))
327327
]
328328
```
329329

@@ -332,7 +332,7 @@ dependencies: [
332332
[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:
333333

334334
target 'YourAppName' do
335-
pod 'UIPilot', '~> 1.2.1'
335+
pod 'UIPilot', '~> 1.3.0'
336336
end
337337

338338
[CocoaPods]: https://cocoapods.org

0 commit comments

Comments
 (0)