Skip to content

Commit 3274da8

Browse files
committed
Use cached navigation title
1 parent 91f172e commit 3274da8

File tree

3 files changed

+48
-28
lines changed

3 files changed

+48
-28
lines changed

Sources/LiveViewNative/Modifiers/NavigationTitleModifier.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,36 @@
88
import SwiftUI
99

1010
struct NavigationTitleModifier: ViewModifier, Decodable, Equatable {
11-
private let title: String
11+
fileprivate let title: String
12+
private let cached: Bool
1213

1314
init(from decoder: Decoder) throws {
1415
let container = try decoder.container(keyedBy: CodingKeys.self)
1516
self.title = try container.decode(String.self, forKey: .title)
17+
self.cached = false
1618
}
1719

18-
init(title: String) {
20+
init(title: String, cached: Bool = false) {
1921
self.title = title
22+
self.cached = cached
2023
}
2124

2225
func body(content: Content) -> some View {
2326
content
2427
.navigationTitle(title)
25-
.preference(key: NavigationTitleModifierKey.self, value: self)
28+
.preference(key: NavigationTitleModifierKey.self, value: cached ? nil : self)
2629
}
2730

2831
enum CodingKeys: String, CodingKey {
2932
case title
3033
}
3134
}
3235

36+
/// A key that passes the navigation title up the View hierarchy via preferences.
3337
enum NavigationTitleModifierKey: PreferenceKey {
3438
static var defaultValue: NavigationTitleModifier?
3539

3640
static func reduce(value: inout NavigationTitleModifier?, nextValue: () -> NavigationTitleModifier?) {
37-
value = nextValue() ?? value
41+
value = nextValue().flatMap({ .init(title: $0.title, cached: true) }) ?? value
3842
}
3943
}

Sources/LiveViewNative/NavStackEntryView.swift

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,33 +41,48 @@ struct NavStackEntryView<R: CustomRegistry>: View {
4141

4242
@ViewBuilder
4343
private var elementTree: some View {
44-
switch coordinator.state {
45-
case .connected:
46-
if let doc = coordinator.document {
47-
coordinator.builder.fromNodes(doc[doc.root()].children(), coordinator: coordinator, url: coordinator.url)
48-
.environment(\.coordinatorEnvironment, CoordinatorEnvironment(coordinator, document: doc))
49-
} else {
50-
fatalError("State is `.connected`, but no `Document` was found.")
51-
}
52-
default:
53-
if R.LoadingView.self == Never.self {
54-
switch coordinator.state {
55-
case .connected:
56-
fatalError()
57-
case .notConnected:
58-
SwiftUI.Text("Not Connected")
59-
case .connecting:
60-
SwiftUI.Text("Connecting")
61-
case .connectionFailed(let error):
62-
SwiftUI.VStack {
63-
SwiftUI.Text("Connection Failed")
64-
.font(.subheadline)
65-
SwiftUI.Text(error.localizedDescription)
44+
if coordinator.url == entry.url {
45+
switch coordinator.state {
46+
case .connected:
47+
if let doc = coordinator.document {
48+
coordinator.builder.fromNodes(doc[doc.root()].children(), coordinator: coordinator, url: coordinator.url)
49+
.environment(\.coordinatorEnvironment, CoordinatorEnvironment(coordinator, document: doc))
50+
.onPreferenceChange(NavigationTitleModifierKey.self) { navigationTitle in
51+
self.liveViewModel.cachedNavigationTitle = navigationTitle
52+
print("Nav title changed")
53+
}
54+
} else {
55+
fatalError("State is `.connected`, but no `Document` was found.")
56+
}
57+
default:
58+
let content = Group {
59+
if R.LoadingView.self == Never.self {
60+
switch coordinator.state {
61+
case .connected:
62+
fatalError()
63+
case .notConnected:
64+
SwiftUI.Text("Not Connected")
65+
case .connecting:
66+
SwiftUI.Text("Connecting")
67+
case .connectionFailed(let error):
68+
SwiftUI.VStack {
69+
SwiftUI.Text("Connection Failed")
70+
.font(.subheadline)
71+
SwiftUI.Text(error.localizedDescription)
72+
}
73+
}
74+
} else {
75+
R.loadingView(for: coordinator.url, state: coordinator.state)
6676
}
6777
}
68-
} else {
69-
R.loadingView(for: coordinator.url, state: coordinator.state)
78+
if let cachedNavigationTitle = liveViewModel.cachedNavigationTitle {
79+
content.modifier(cachedNavigationTitle)
80+
} else {
81+
content
82+
}
7083
}
84+
} else if let cachedNavigationTitle = liveViewModel.cachedNavigationTitle {
85+
SwiftUI.Text("").modifier(cachedNavigationTitle)
7186
}
7287
}
7388
}

Sources/LiveViewNative/ViewModel.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import LiveViewNativeCore
1414
/// In a view in the LiveView tree, a model can be obtained using `@EnvironmentObject`.
1515
public class LiveViewModel<R: CustomRegistry>: ObservableObject {
1616
private var forms = [String: FormModel]()
17+
var cachedNavigationTitle: NavigationTitleModifier?
1718

1819
/// Get or create a ``FormModel`` for the `<form>` element with the given ID.
1920
public func getForm(elementID id: String) -> FormModel {

0 commit comments

Comments
 (0)