Skip to content

Commit

Permalink
Merge pull request #3 from alperozturk96/feature/navigation-animations
Browse files Browse the repository at this point in the history
Navigation Animations are added
  • Loading branch information
alperozturk96 authored Sep 2, 2023
2 parents 04487df + fa77397 commit e5ed702
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 9 deletions.
21 changes: 21 additions & 0 deletions Sources/Navigator/NavigationAnimation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// NavigationAnimation.swift
//
//
// Created by Alper Ozturk on 2.09.2023.
//

import Foundation
import UIKit

public struct NavigationAnimation {
let transitionType: CATransitionType
let mediaTimingFunction: CAMediaTimingFunctionName
let duration: CFTimeInterval

public init(transitionType: CATransitionType, mediaTimingFunction: CAMediaTimingFunctionName, duration: CFTimeInterval) {
self.transitionType = transitionType
self.mediaTimingFunction = mediaTimingFunction
self.duration = duration
}
}
10 changes: 5 additions & 5 deletions Sources/Navigator/Navigator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public struct Navigator {
public static func pop() {
assert(Thread.isMainThread, "Must be run on main thread")

UIApplication.shared.getNavigationController()?.popViewController(animated: true)
UIApplication.shared.pop()
}

/// Goes back to first element in the navigation stack.
Expand All @@ -26,18 +26,18 @@ public struct Navigator {
/// e.g Before: A (title: "Home") -> B (title: "Item List") -> C (title: "Item Detail Page") -> D (title: "User Page")
/// After: popTo(Item List) A -> B
@discardableResult
public static func popTo(_ navigationBarTitle: String) -> Bool {
public static func popTo(_ navigationBarTitle: String, animation: NavigationAnimation? = nil) -> Bool {
assert(Thread.isMainThread, "Must be run on main thread")

return UIApplication.shared.popToView(navigationBarTitle)
return UIApplication.shared.popToView(navigationBarTitle, animation: animation)
}

/// Add new element in the navigation stack. For first use NavigationView must be used.
/// e.g Before: A -> B -> C | After: A -> B -> C -> D
public static func push<V: View>(_ view: V, title: String? = nil) {
public static func push<V: View>(_ view: V, animation: NavigationAnimation? = nil, title: String? = nil) {
assert(Thread.isMainThread, "Must be run on main thread")

UIApplication.shared.pushToView(view: view, title: title)
UIApplication.shared.pushToView(view: view, animation: animation, title: title)
}

/// Remove all elements from navigation stack.
Expand Down
34 changes: 30 additions & 4 deletions Sources/Navigator/UIApplicationExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import UIKit
import SwiftUI

// MARK: - UIWindow
extension UIApplication {
var firstWindow: UIWindow? {
return UIApplication.shared.connectedScenes
Expand All @@ -16,8 +17,11 @@ extension UIApplication {
.flatMap({ $0 as? UIWindowScene })?.windows
.first(where: \.isKeyWindow)
}

func presentModal<V: View>(view: V, title: String? = nil) {
}

// MARK: - Navigations
extension UIApplication {
func presentModal<V: View>(view: V, title: String?) {
guard let navigationController = getNavigationController() else {
return
}
Expand All @@ -33,7 +37,7 @@ extension UIApplication {
}
}

func pushToView<V: View>(view: V, title: String? = nil) {
func pushToView<V: View>(view: V, animation: NavigationAnimation?, title: String?) {
guard let navigationController = getNavigationController() else {
return
}
Expand All @@ -45,18 +49,24 @@ extension UIApplication {
}

if !navigationController.children.contains(targetVC) {
if let animation {
addTransition(vc: targetVC, animation: animation)
}
navigationController.pushViewController(targetVC, animated: true)
}
}

@discardableResult
func popToView(_ navigationBarTitle: String) -> Bool {
func popToView(_ navigationBarTitle: String, animation: NavigationAnimation?) -> Bool {
guard let navigationController = getNavigationController() else {
return false
}

for vc in navigationController.children {
if vc.navigationItem.title == navigationBarTitle {
if let animation {
addTransition(vc: vc, animation: animation)
}
navigationController.popToViewController(vc, animated: true)
return true
}
Expand All @@ -65,6 +75,14 @@ extension UIApplication {
return false
}

func pop() {
guard let navigationController = getNavigationController() else {
return
}

navigationController.popViewController(animated: true)
}

func setNavigationStack<V: View>(views: [V]) {
guard let window = firstWindow else { return }

Expand Down Expand Up @@ -108,6 +126,14 @@ extension UIApplication {
return navigationController
}

private func addTransition(vc: UIViewController, animation: NavigationAnimation) {
let transition = CATransition()
transition.duration = animation.duration
transition.timingFunction = CAMediaTimingFunction(name: animation.mediaTimingFunction)
transition.type = animation.transitionType
vc.view.layer.add(transition, forKey: nil)
}

private func findNavigationController(viewController: UIViewController?) -> UINavigationController? {
guard let vc = viewController else {
return nil
Expand Down

0 comments on commit e5ed702

Please sign in to comment.