Skip to content

Commit

Permalink
Code Refactorisation + Bug Fixes
Browse files Browse the repository at this point in the history
feat:
- Added ability to change the background colour of screens within the entire application
  • Loading branch information
FulcrumOne authored Jun 7, 2023
1 parent b9e730b commit 70f9cff
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Sources/Navigattie/Extensions/Foundation/Array++.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ extension Array {
}}
}
extension Array {
var isNextToLast: Element? { count >= 2 ? self[count - 2] : nil }
var nextToLast: Element? { count >= 2 ? self[count - 2] : nil }
}
22 changes: 0 additions & 22 deletions Sources/Navigattie/Extensions/Views/View++.swift

This file was deleted.

4 changes: 2 additions & 2 deletions Sources/Navigattie/Managers/NavigationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public extension NavigationManager {
static func pop() { performOperation(.removeLast) }

/// Returns to view with provided type
static func pop<N: NavigatableView>(to view: N) { performOperation(.removeAll(toID: view.id)) }
static func pop<N: NavigatableView>(to view: N.Type) { performOperation(.removeAll(toID: .init(describing: view))) }

/// Returns to a root view
static func popToRoot() { performOperation(.removeAllExceptFirst) }
Expand Down Expand Up @@ -48,7 +48,7 @@ private extension NavigationManager {

// MARK: - Setters
extension NavigationManager {
static func setRoot(_ rootView: some NavigatableView) { shared.views = [.init(rootView, .no)] }
static func setRoot(_ rootView: some NavigatableView) { DispatchQueue.main.async { shared.views = [.init(rootView, .no)] }}
static func setNamespace(_ value: Namespace.ID) { if shared.namespace == nil { shared.namespace = value } }
static func blockTransitions(_ value: Bool) { shared.transitionsBlocked = value }
}
Expand Down
21 changes: 3 additions & 18 deletions Sources/Navigattie/Protocols/NavigatableView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,11 @@
import SwiftUI

public protocol NavigatableView: View {
var backgroundColour: Color { get }
/// OPTIONAL: Changes the background colour of the selected view
var backgroundColour: Color? { get }
}

// MARK: - Pushing and Removing From Stack
public extension NavigatableView {
/// Pushes a new view. Stacks previous one
func push(with animation: TransitionAnimation) { NavigationManager.push(self, animation) }
}
public extension NavigatableView {
/// Removes the current view from the stack
func pop() { NavigationManager.pop() }

/// Removes all views up to the selected view in the stack. The view from the argument will be the new active view
func pop<N: NavigatableView>(to view: N) { NavigationManager.pop(to: view) }

/// Removes all views from the stack. Root view will be the new active view
func popToRoot() { NavigationManager.popToRoot() }
}

// MARK: - Others
// MARK: - Internals
extension NavigatableView {
var id: String { .init(describing: Self.self) }
}
38 changes: 38 additions & 0 deletions Sources/Navigattie/Public/Public+NavigatableView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// Public+NavigatableView.swift of Navigattie
//
// Created by Tomasz Kurylik
// - Twitter: https://twitter.com/tkurylik
// - Mail: [email protected]
//
// Copyright ©2023 Mijick. Licensed under MIT License.


import SwiftUI

// MARK: - Initialising
public extension NavigatableView {
func implementNavigationView(config: NavigationConfig? = nil) -> some View { NavigationView(rootView: self, config: config) }
}

// MARK: - Pushing And Removing Views From Stack
public extension NavigatableView {
/// Pushes a new view. Stacks previous one
func push(with animation: TransitionAnimation) { NavigationManager.push(self, animation) }
}
public extension View {
/// Removes the presented view from the stack
func pop() { NavigationManager.pop() }

/// Removes all views up to the selected view in the stack. The view from the argument will be the new active view
func pop<N: NavigatableView>(to view: N.Type) { NavigationManager.pop(to: view) }

/// Removes all views from the stack. Root view will be the new active view
func popToRoot() { NavigationManager.popToRoot() }
}

// MARK: - Configurable
public extension NavigatableView {
/// OPTIONAL: Changes the background colour of the selected view
var backgroundColour: Color? { nil }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// NavigatableView++.swift of Navigattie
// Public+NavigationConfig.swift of Navigattie
//
// Created by Tomasz Kurylik
// - Twitter: https://twitter.com/tkurylik
Expand All @@ -10,6 +10,8 @@

import SwiftUI

public extension NavigatableView {
func implementNavigationView() -> some View { NavigationView(rootView: self) }
public class NavigationConfig {
public var backgroundColour: Color = .clear

public init() {}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// TransitionAnimation.swift of Navigattie
// Public+TransitionAnimation.swift of Navigattie
//
// Created by Tomasz Kurylik
// - Twitter: https://twitter.com/tkurylik
Expand All @@ -8,8 +8,6 @@
// Copyright ©2023 Mijick. Licensed under MIT License.


import Foundation

public enum TransitionAnimation {
case no
case dissolve
Expand Down
2 changes: 1 addition & 1 deletion Sources/Navigattie/Type Erasers/AnyNavigatableView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import SwiftUI
struct AnyNavigatableView: NavigatableView, Equatable {
let id: String
let animation: TransitionAnimation
let backgroundColour: Color
let backgroundColour: Color?
private let _body: AnyView


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ extension View {
func onAnimationCompleted<V: VectorArithmetic>(for value: V, perform action: @escaping () -> ()) -> some View { modifier(Modifier(observedValue: value, completion: action)) }
}


// MARK: - Implementation
fileprivate struct Modifier<V: VectorArithmetic>: AnimatableModifier {
var animatableData: V { didSet { notifyCompletionIfFinished() }}
Expand Down
16 changes: 11 additions & 5 deletions Sources/Navigattie/Views/NavigationStackView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ struct NavigationStackView: View {
@State private var animatableOpacity: CGFloat = 1
@State private var animatableOffset: CGFloat = 0
@State private var animatableScale: CGFloat = 0
private let config: NavigationConfig


init(namespace: Namespace.ID) { self._temporaryViews = .init(initialValue: NavigationManager.shared.views); NavigationManager.setNamespace(namespace) }
init(namespace: Namespace.ID, config: NavigationConfig) { self._temporaryViews = .init(initialValue: NavigationManager.shared.views); self.config = config; NavigationManager.setNamespace(namespace) }
var body: some View {
ZStack(content: createStack)
.onChange(of: stack.views, perform: onViewsChanged)
Expand All @@ -36,14 +37,19 @@ private extension NavigationStackView {
func createItem(_ item: AnyNavigatableView) -> some View {
item
.scaleEffect(getScale(item))
.background(item.backgroundColour)
.background(getBackground(item))
.transition(.identity)
.opacity(getOpacity(item))
.offset(getOffset(item))
.compositingGroup()
}
}

// MARK: - Getting Background
private extension NavigationStackView {
func getBackground(_ item: AnyNavigatableView) -> Color { item.backgroundColour ?? config.backgroundColour }
}

// MARK: - Calculating Opacity
private extension NavigationStackView {
func getOpacity(_ view: AnyNavigatableView) -> CGFloat {
Expand All @@ -59,7 +65,7 @@ private extension NavigationStackView {
}
private extension NavigationStackView {
func checkOpacityPrerequisites(_ view: AnyNavigatableView) throws {
if !view.isOne(of: stack.views.last, temporaryViews.last, temporaryViews.isNextToLast) { throw "Opacity can concern the last or next to last element of the stack" }
if !view.isOne(of: temporaryViews.last, temporaryViews.nextToLast) { throw "Opacity can concern the last or next to last element of the stack" }
}
func isLastView(_ view: AnyNavigatableView) -> Bool {
let lastView = stack.transitionType == .push ? temporaryViews.last : stack.views.last
Expand Down Expand Up @@ -93,7 +99,7 @@ private extension NavigationStackView {
private extension NavigationStackView {
func checkOffsetPrerequisites(_ view: AnyNavigatableView) throws {
if !stack.transitionAnimation.isOne(of: .horizontalSlide, .verticalSlide) { throw "Offset cannot be set for a non-slide transition type" }
if !view.isOne(of: stack.views.last, temporaryViews.last, temporaryViews.isNextToLast) { throw "Offset can concern the last or next to last element of the stack" }
if !view.isOne(of: temporaryViews.last, temporaryViews.nextToLast) { throw "Offset can concern the last or next to last element of the stack" }
}
func calculateSlideOffsetValue(_ view: AnyNavigatableView) -> CGFloat {
switch view == temporaryViews.last {
Expand Down Expand Up @@ -126,7 +132,7 @@ private extension NavigationStackView {
private extension NavigationStackView {
func checkScalePrerequisites(_ view: AnyNavigatableView) throws {
if !stack.transitionAnimation.isOne(of: .scale) { throw "Scale cannot be set for a non-scale transition type" }
if !view.isOne(of: temporaryViews.last, temporaryViews.isNextToLast) { throw "Scale can concern the last or next to last element of the stack" }
if !view.isOne(of: temporaryViews.last, temporaryViews.nextToLast) { throw "Scale can concern the last or next to last element of the stack" }
}
func calculateScaleValue(_ view: AnyNavigatableView) -> CGFloat {
switch view == temporaryViews.last {
Expand Down
6 changes: 4 additions & 2 deletions Sources/Navigattie/Views/NavigationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import SwiftUI

struct NavigationView: View {
@Namespace var namespace
private let config: NavigationConfig

init(rootView: some NavigatableView) { NavigationManager.setRoot(rootView) }
var body: some View { NavigationStackView(namespace: namespace) }

init(rootView: some NavigatableView, config: NavigationConfig?) { self.config = config ?? .init(); NavigationManager.setRoot(rootView) }
var body: some View { NavigationStackView(namespace: namespace, config: config) }
}

0 comments on commit 70f9cff

Please sign in to comment.