Skip to content

Commit

Permalink
Merge branch 'bugfix/support-inheritance'
Browse files Browse the repository at this point in the history
  • Loading branch information
johnpatrickmorgan committed Feb 23, 2023
2 parents fcaaec1 + 11ae789 commit a3b1ce3
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 9 deletions.
22 changes: 22 additions & 0 deletions NavigationBackportApp/Shared/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ struct NumberList: Hashable, Codable {
let range: Range<Int>
}

class ClassDestination {
let data: String

init(data: String) {
self.data = data
}
}

extension ClassDestination: Hashable {
static func == (lhs: ClassDestination, rhs: ClassDestination) -> Bool {
lhs.data == rhs.data
}

func hash(into hasher: inout Hasher) {
hasher.combine(data)
}
}

class SampleClassDestination: ClassDestination {
init() { super.init(data: "sample data") }
}

struct ContentView: View {
var body: some View {
TabView {
Expand Down
18 changes: 18 additions & 0 deletions NavigationBackportApp/Shared/NBNavigationPathView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ struct NBNavigationPathView: View {
.nbNavigationDestination(for: EmojiVisualisation.self, destination: { visualisation in
EmojiView(visualisation: visualisation)
})
.nbNavigationDestination(for: ClassDestination.self, destination: { destination in
ClassDestinationView(destination: destination)
})
}
}
}
Expand Down Expand Up @@ -56,6 +59,8 @@ private struct HomeView: View {
NBNavigationLink(value: NumberList(range: 0 ..< 100), label: { Text("Pick a number") })
// Push via navigator
Button("99 Red balloons", action: show99RedBalloons)
// Push child class via navigator
Button("Show ClassDestination", action: showClassDestination)
// Push via Bool binding
VStack {
Text("Push local destination")
Expand All @@ -76,6 +81,10 @@ private struct HomeView: View {
$0.append(EmojiVisualisation(emoji: "🎈", count: 99))
}
}

func showClassDestination() {
navigator.push(SampleClassDestination())
}
}

private struct NumberListView: View {
Expand Down Expand Up @@ -122,3 +131,12 @@ private struct EmojiView: View {
.navigationTitle("Visualise \(visualisation.count)")
}
}

private struct ClassDestinationView: View {
let destination: ClassDestination

var body: some View {
Text(destination.data)
.navigationTitle("A ClassDestination")
}
}
18 changes: 18 additions & 0 deletions NavigationBackportApp/Shared/NoBindingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ struct NoBindingView: View {
.nbNavigationDestination(for: EmojiVisualisation.self, destination: { visualisation in
EmojiView(visualisation: visualisation)
})
.nbNavigationDestination(for: ClassDestination.self, destination: { destination in
ClassDestinationView(destination: destination)
})
}
}
}
Expand All @@ -28,6 +31,8 @@ private struct HomeView: View {
NBNavigationLink(value: NumberList(range: 0 ..< 100), label: { Text("Pick a number") })
// Push via navigator
Button("99 Red balloons", action: show99RedBalloons)
// Push child class via navigator
Button("Show ClassDestination", action: showClassDestination)
// Push via Bool binding
VStack {
Text("Push local destination")
Expand All @@ -46,6 +51,10 @@ private struct HomeView: View {
$0.append(EmojiVisualisation(emoji: "🎈", count: 99))
}
}

func showClassDestination() {
navigator.push(SampleClassDestination())
}
}

private struct NumberListView: View {
Expand Down Expand Up @@ -94,3 +103,12 @@ private struct EmojiView: View {
.navigationTitle("Visualise \(visualisation.count)")
}
}

private struct ClassDestinationView: View {
let destination: ClassDestination

var body: some View {
Text(destination.data)
.navigationTitle("A ClassDestination")
}
}
24 changes: 15 additions & 9 deletions Sources/NavigationBackport/DestinationBuilderHolder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,24 @@ class DestinationBuilderHolder: ObservableObject {

func build<T>(_ typedData: T) -> AnyView {
let base = (typedData as? AnyHashable)?.base
let type = type(of: base ?? typedData)
let key: String
if let identifier = (base ?? typedData) as? LocalDestinationID {
key = identifier.rawValue.uuidString
let key = identifier.rawValue.uuidString
if let builder = builders[key], let output = builder(typedData) {
return output
}
assertionFailure("No view builder found for type \(key)")
} else {
key = Self.identifier(for: type)
}

if let builder = builders[key], let output = builder(typedData) {
return output
var possibleMirror: Mirror? = Mirror(reflecting: base ?? typedData)
while let mirror = possibleMirror {
let key = Self.identifier(for: mirror.subjectType)

if let builder = builders[key], let output = builder(typedData) {
return output
}
possibleMirror = mirror.superclassMirror
}
assertionFailure("No view builder found for type \(type(of: base ?? typedData))")
}
assertionFailure("No view builder found for key \(key)")
return AnyView(Image(systemName: "exclamationmark.triangle"))
}
}

0 comments on commit a3b1ce3

Please sign in to comment.