-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
354dccf
commit 7942f39
Showing
90 changed files
with
4,386 additions
and
1 deletion.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// | ||
// NavigationTransitionController+Delegate.swift | ||
// NavigationTransitionController | ||
// | ||
// Created by Joshua Choi on 11/27/20. | ||
// Copyright © 2020 Nanolens, Inc. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
|
||
|
||
|
||
// MARK: - UIGestureRecognizerDelegate | ||
extension NavigationTransitionController: UIGestureRecognizerDelegate { | ||
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { | ||
// MARK: - NavigationTransitionType | ||
switch type { | ||
case .standard: | ||
// Disable the pan gesture from moving to the left along the x-axis | ||
return gestureRecognizer == panGestureRecognizer && panGestureRecognizer.velocity(in: nil).x > 0.0 | ||
case .zoom, .presentation: | ||
// Disable the pan gesture from moving up along the y-axis or x-axis | ||
return gestureRecognizer == panGestureRecognizer && (panGestureRecognizer.velocity(in: nil).y > 0.0 || abs(panGestureRecognizer.velocity(in: nil).x) > abs(panGestureRecognizer.velocity(in: nil).x)) | ||
default: | ||
// By default, allow the pan gesture to begin | ||
return true | ||
} | ||
} | ||
|
||
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { | ||
// MARK: - UIScrollView | ||
if let scrollView = (gestureRecognizer == panGestureRecognizer ? otherGestureRecognizer : panGestureRecognizer).view as? UIScrollView, type == .presentation { | ||
// Allow the gesture recognizer to work simultaneously with the scroll view only if the scroll view has reached the top-edge | ||
return scrollView.contentOffset.y <= scrollView.contentInset.top | ||
} else if type == .fade { | ||
// If the NavigationTransitionType is fade, allow it to begin | ||
return true | ||
} else { | ||
return false | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
// MARK: - UIViewControllerTransitioningDelegate | ||
extension NavigationTransitionController: UIViewControllerTransitioningDelegate { | ||
public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { | ||
return self | ||
} | ||
|
||
public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { | ||
return self | ||
} | ||
|
||
public func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { | ||
return isInteractivelyDriven ? percentDrivenInteractiveTransition : nil | ||
} | ||
|
||
public func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { | ||
return isInteractivelyDriven ? percentDrivenInteractiveTransition : nil | ||
} | ||
} | ||
|
||
|
||
|
||
// MARK: - UIViewControllerAnimatedTransitioning | ||
extension NavigationTransitionController: UIViewControllerInteractiveTransitioning { | ||
public var wantsInteractiveStart: Bool { | ||
return false | ||
} | ||
|
||
public var completionSpeed: CGFloat { | ||
return 0.0 | ||
} | ||
|
||
public func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) { | ||
// Only forward calls to this class' UIViewControllerAnimatedTransitioning protocol if we're not interactively driving the transition | ||
guard isInteractivelyDriven == false else { | ||
return | ||
} | ||
print("\(#file)/\(#line) - \(classForCoder) forwarding interactive transition to animated transitioning delegate") | ||
// Call the UIViewControllerAnimatedTransitioning | ||
self.animateTransition(using: transitionContext) | ||
} | ||
} | ||
|
||
|
||
|
||
// MARK: - UIViewControllerAnimatedTransitioning | ||
extension NavigationTransitionController: UIViewControllerAnimatedTransitioning { | ||
public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { | ||
return animationDuration | ||
} | ||
|
||
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { | ||
// MARK: - TransitionContext | ||
self.transitionContext = transitionContext | ||
|
||
// MARK: - NavigationTransitionOperation | ||
switch navigationTransitionOperation { | ||
case .present: | ||
// Apply the presentation animation transition | ||
applyPresentationTransition(transitionContext: transitionContext) | ||
|
||
case .dismiss: | ||
// Apply the dismissal animation transition | ||
applyDismissalTransition(transitionContext: transitionContext) | ||
|
||
} | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// | ||
// NavigationTransitionCoordinator.swift | ||
// NavigationTransitionController | ||
// | ||
// Created by Joshua Choi on 11/16/20. | ||
// Copyright © 2020 Nanolens, Inc. All rights reserved. | ||
// | ||
|
||
|
||
import QuartzCore | ||
|
||
func clip<T : Comparable>(_ x0: T, _ x1: T, _ v: T) -> T { | ||
return max(x0, min(x1, v)) | ||
} | ||
|
||
func lerp<T : FloatingPoint>(_ v0: T, _ v1: T, _ t: T) -> T { | ||
return v0 + (v1 - v0) * t | ||
} | ||
|
||
|
||
func -(lhs: CGPoint, rhs: CGPoint) -> CGVector { | ||
return CGVector(dx: lhs.x - rhs.x, dy: lhs.y - rhs.y) | ||
} | ||
|
||
func -(lhs: CGPoint, rhs: CGVector) -> CGPoint { | ||
return CGPoint(x: lhs.x - rhs.dx, y: lhs.y - rhs.dy) | ||
} | ||
|
||
func -(lhs: CGVector, rhs: CGVector) -> CGVector { | ||
return CGVector(dx: lhs.dx - rhs.dx, dy: lhs.dy - rhs.dy) | ||
} | ||
|
||
func +(lhs: CGPoint, rhs: CGPoint) -> CGVector { | ||
return CGVector(dx: lhs.x + rhs.x, dy: lhs.y + rhs.y) | ||
} | ||
|
||
func +(lhs: CGPoint, rhs: CGVector) -> CGPoint { | ||
return CGPoint(x: lhs.x + rhs.dx, y: lhs.y + rhs.dy) | ||
} | ||
|
||
func +(lhs: CGVector, rhs: CGVector) -> CGVector { | ||
return CGVector(dx: lhs.dx + rhs.dx, dy: lhs.dy + rhs.dy) | ||
} | ||
|
||
func *(left: CGVector, right:CGFloat) -> CGVector { | ||
return CGVector(dx: left.dx * right, dy: left.dy * right) | ||
} | ||
|
||
extension CGPoint { | ||
var vector: CGVector { | ||
return CGVector(dx: x, dy: y) | ||
} | ||
} | ||
|
||
extension CGVector { | ||
var magnitude: CGFloat { | ||
return sqrt(dx*dx + dy*dy) | ||
} | ||
|
||
var point: CGPoint { | ||
return CGPoint(x: dx, y: dy) | ||
} | ||
|
||
func apply(transform t: CGAffineTransform) -> CGVector { | ||
return point.applying(t).vector | ||
} | ||
} | ||
|
||
public extension CGFloat { | ||
/// Returns the value, scaled-and-shifted to the targetRange. If no target range is provided, we assume the unit range (0, 1) | ||
static func scaleAndShift( | ||
value: CGFloat, | ||
inRange: (min: CGFloat, max: CGFloat), | ||
toRange: (min: CGFloat, max: CGFloat) = (min: 0.0, max: 1.0) | ||
) -> CGFloat { | ||
assert(inRange.max > inRange.min) | ||
assert(toRange.max > toRange.min) | ||
|
||
if value < inRange.min { | ||
return toRange.min | ||
} else if value > inRange.max { | ||
return toRange.max | ||
} else { | ||
let ratio = (value - inRange.min) / (inRange.max - inRange.min) | ||
return toRange.min + ratio * (toRange.max - toRange.min) | ||
} | ||
} | ||
} | ||
|
||
|
Oops, something went wrong.