Skip to content

Commit 0ec329d

Browse files
authored
Add DirectionalNavigationAdapter.onNavigation (#669)
1 parent 8bd799d commit 0ec329d

File tree

2 files changed

+48
-14
lines changed

2 files changed

+48
-14
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
All notable changes to this project will be documented in this file. Take a look at [the migration guide](docs/Migration%20Guide.md) to upgrade between two major versions.
44

5-
<!-- ## [Unreleased] -->
5+
## [Unreleased]
6+
7+
### Added
8+
9+
#### Navigator
10+
11+
* Added `DirectionalNavigationAdapter.onNavigation` callback to be notified when a navigation action is triggered.
12+
* This callback is called before executing any navigation action.
13+
* Useful for hiding UI elements when the user navigates, or implementing analytics.
14+
615

716
## [3.5.0]
817

Sources/Navigator/DirectionalNavigationAdapter.swift

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ public final class DirectionalNavigationAdapter {
100100
private let pointerPolicy: PointerPolicy
101101
private let keyboardPolicy: KeyboardPolicy
102102
private let animatedTransition: Bool
103+
private let onNavigation: @MainActor () -> Void
103104

105+
@available(*, deprecated, message: "Use `bind(to:)` instead of notifying the event yourself. See the migration guide.")
104106
private weak var navigator: VisualNavigator?
105107

106108
/// Initializes a new `DirectionalNavigationAdapter`.
@@ -110,14 +112,17 @@ public final class DirectionalNavigationAdapter {
110112
/// - keyboardPolicy: Policy on page turns using the keyboard.
111113
/// - animatedTransition: Indicates whether the page turns should be
112114
/// animated.
115+
/// - onNavigation: Callback called when a navigation is triggered.
113116
public init(
114117
pointerPolicy: PointerPolicy = PointerPolicy(),
115118
keyboardPolicy: KeyboardPolicy = KeyboardPolicy(),
116-
animatedTransition: Bool = false
119+
animatedTransition: Bool = false,
120+
onNavigation: @escaping @MainActor () -> Void = {}
117121
) {
118122
self.pointerPolicy = pointerPolicy
119123
self.keyboardPolicy = keyboardPolicy
120124
self.animatedTransition = animatedTransition
125+
self.onNavigation = onNavigation
121126
}
122127

123128
/// Binds the adapter to the given visual navigator.
@@ -162,7 +167,6 @@ public final class DirectionalNavigationAdapter {
162167
}
163168

164169
let bounds = navigator.view.bounds
165-
let options = NavigatorGoOptions(animated: animatedTransition)
166170

167171
if pointerPolicy.edges.contains(.horizontal) {
168172
let horizontalEdgeSize = pointerPolicy.horizontalEdgeThresholdPercent
@@ -172,9 +176,9 @@ public final class DirectionalNavigationAdapter {
172176
let rightRange = (bounds.width - horizontalEdgeSize) ... bounds.width
173177

174178
if rightRange.contains(point.x) {
175-
return await navigator.goRight(options: options)
179+
return await goRight(in: navigator)
176180
} else if leftRange.contains(point.x) {
177-
return await navigator.goLeft(options: options)
181+
return await goLeft(in: navigator)
178182
}
179183
}
180184

@@ -186,9 +190,9 @@ public final class DirectionalNavigationAdapter {
186190
let bottomRange = (bounds.height - verticalEdgeSize) ... bounds.height
187191

188192
if bottomRange.contains(point.y) {
189-
return await navigator.goForward(options: options)
193+
return await goForward(in: navigator)
190194
} else if topRange.contains(point.y) {
191-
return await navigator.goBackward(options: options)
195+
return await goBackward(in: navigator)
192196
}
193197
}
194198

@@ -200,24 +204,44 @@ public final class DirectionalNavigationAdapter {
200204
return false
201205
}
202206

203-
let options = NavigatorGoOptions(animated: animatedTransition)
204-
205207
switch event.key {
206208
case .arrowUp where keyboardPolicy.handleArrowKeys:
207-
return await navigator.goBackward(options: options)
209+
return await goBackward(in: navigator)
208210
case .arrowDown where keyboardPolicy.handleArrowKeys:
209-
return await navigator.goForward(options: options)
211+
return await goForward(in: navigator)
210212
case .arrowLeft where keyboardPolicy.handleArrowKeys:
211-
return await navigator.goLeft(options: options)
213+
return await goLeft(in: navigator)
212214
case .arrowRight where keyboardPolicy.handleArrowKeys:
213-
return await navigator.goRight(options: options)
215+
return await goRight(in: navigator)
214216
case .space where keyboardPolicy.handleSpaceKey:
215-
return await navigator.goForward(options: options)
217+
return await goForward(in: navigator)
216218
default:
217219
return false
218220
}
219221
}
220222

223+
@MainActor private func goBackward(in navigator: VisualNavigator) async -> Bool {
224+
await go { await navigator.goBackward(options: $0) }
225+
}
226+
227+
@MainActor private func goForward(in navigator: VisualNavigator) async -> Bool {
228+
await go { await navigator.goForward(options: $0) }
229+
}
230+
231+
@MainActor private func goLeft(in navigator: VisualNavigator) async -> Bool {
232+
await go { await navigator.goLeft(options: $0) }
233+
}
234+
235+
@MainActor private func goRight(in navigator: VisualNavigator) async -> Bool {
236+
await go { await navigator.goRight(options: $0) }
237+
}
238+
239+
@MainActor private func go(_ action: (NavigatorGoOptions) async -> Bool) async -> Bool {
240+
onNavigation()
241+
let options = NavigatorGoOptions(animated: animatedTransition)
242+
return await action(options)
243+
}
244+
221245
@available(*, deprecated, message: "Use the new initializer without the navigator parameter and call `bind(to:)`. See the migration guide.")
222246
public init(
223247
navigator: VisualNavigator,
@@ -240,6 +264,7 @@ public final class DirectionalNavigationAdapter {
240264
)
241265
keyboardPolicy = KeyboardPolicy()
242266
self.animatedTransition = animatedTransition
267+
onNavigation = {}
243268
}
244269

245270
@available(*, deprecated, message: "Use `bind(to:)` instead of notifying the event yourself. See the migration guide.")

0 commit comments

Comments
 (0)