Skip to content

Commit

Permalink
Patch 0.6.0
Browse files Browse the repository at this point in the history
feat:
- Added ability to change the root in the navigation stack (#18)
  • Loading branch information
FulcrumOne committed May 22, 2024
1 parent daa757f commit fa766b7
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 27 deletions.
13 changes: 13 additions & 0 deletions Sources/Internal/Extensions/Array++.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,16 @@ extension Array {
extension Array {
var nextToLast: Element? { count >= 2 ? self[count - 2] : nil }
}


// MARK: - Equatable Elements
extension Array where Element: Equatable {
func appendingAsFirstAndRemovingDuplicates(_ newElement: Element) -> [Element] {
var elements = self

elements.removeAll(where: { $0 == newElement })
elements[0] = newElement

return elements
}
}
17 changes: 0 additions & 17 deletions Sources/Internal/Extensions/UIApplication++.swift

This file was deleted.

20 changes: 12 additions & 8 deletions Sources/Internal/Managers/NavigationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import SwiftUI

public class NavigationManager: ObservableObject {
@Published private(set) var views: [AnyNavigatableView] = [] { willSet { onViewsWillUpdate(newValue) } }
private(set) var transitionsBlocked: Bool = false
private(set) var transitionsBlocked: Bool = false { didSet { onTransitionsBlockedUpdate() } }
private(set) var transitionType: TransitionType = .push
private(set) var transitionAnimation: TransitionAnimation = .no

Expand All @@ -21,9 +21,6 @@ public class NavigationManager: ObservableObject {
}

// MARK: - Operations Handler
extension NavigationManager {
static func push(_ view: some NavigatableView, _ animation: TransitionAnimation) { performOperation(.insert(view, animation)) }
}
extension NavigationManager {
static func performOperation(_ operation: Operation) { if !NavigationManager.shared.transitionsBlocked {
DispatchQueue.main.async { shared.views.perform(operation) }
Expand All @@ -33,19 +30,26 @@ extension NavigationManager {
// MARK: - Setters
extension NavigationManager {
static func setRoot(_ rootView: some NavigatableView) { DispatchQueue.main.async { shared.views = [.init(rootView, .no)] }}
static func replaceRoot(_ newRootView: some NavigatableView) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { shared.transitionType = .replaceRoot(.init(newRootView, .no)) }}
static func blockTransitions(_ value: Bool) { shared.transitionsBlocked = value }
}

// MARK: - On Views Will Update
// MARK: - On Attributes Will/Did Change
private extension NavigationManager {
func onViewsWillUpdate(_ newValue: [AnyNavigatableView]) {
transitionType = newValue.count > views.count ? .push : .pop
transitionType = newValue.count > views.count || !transitionType.isOne(of: .push, .pop) ? .push : .pop
transitionAnimation = (transitionType == .push ? newValue.last?.animation : views.last?.animation) ?? .no
}
func onTransitionsBlockedUpdate() { if !transitionsBlocked, case let .replaceRoot(newRootView) = transitionType {
views = views.appendingAsFirstAndRemovingDuplicates(newRootView)
}}
}

// MARK: - Transition Type
enum TransitionType { case pop, push }
extension NavigationManager { enum TransitionType: Equatable {
case pop, push
case replaceRoot(AnyNavigatableView)
}}

// MARK: - Array Operations
extension NavigationManager { enum Operation {
Expand All @@ -60,7 +64,7 @@ fileprivate extension [AnyNavigatableView] {
}
private extension [AnyNavigatableView] {
func hideKeyboard() {
UIApplication.shared.hideKeyboard()
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
mutating func performOperation(_ operation: NavigationManager.Operation) {
switch operation {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Internal/Views/NavigationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private extension NavigationView {
NavigationManager.blockTransitions(true)
}
func updateTemporaryViews(_ views: [AnyNavigatableView]) { switch stack.transitionType {
case .push: temporaryViews = views
case .push, .replaceRoot: temporaryViews = views
case .pop: temporaryViews = views + [temporaryViews.last].compactMap { $0 }
}}
func resetOffsetAndOpacity() {
Expand Down
5 changes: 4 additions & 1 deletion Sources/Public/Public+NavigatableView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ public extension NavigatableView {
// MARK: - Pushing Views To Stack
public extension NavigatableView {
/// Pushes a new view. Stacks previous one
func push(with animation: TransitionAnimation) { NavigationManager.push(self, animation) }
@discardableResult func push(with animation: TransitionAnimation) -> Self { NavigationManager.performOperation(.insert(self, animation)); return self }

/// Sets the selected view as the new navigation root
@discardableResult func setAsNewRoot() -> Self { NavigationManager.replaceRoot(self); return self }
}

0 comments on commit fa766b7

Please sign in to comment.