Last active
July 14, 2022 17:57
-
-
Save ChrisMarshallNY/0a0ecab9395cad51af3aadf967beccfd to your computer and use it in GitHub Desktop.
A UIViewController Fade Animator
This file contains hidden or 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
import UIKit | |
/* ###################################################################################################################################### */ | |
// MARK: Fade Transition Animator | |
/* ###################################################################################################################################### */ | |
/** | |
This allows us to do a fade between two screens. | |
It was inspired by [this Medium post](https://medium.com/@ludvigeriksson/custom-interactive-uinavigationcontroller-transition-animations-in-swift-4-a4b5e0cefb1e) | |
*/ | |
open class RVS_FadeAnimator: NSObject, UIViewControllerAnimatedTransitioning { | |
/* ################################################################## */ | |
/** | |
This is set to true, if the operation is a "push," and false, if it is a "pop." | |
*/ | |
private var _presenting: Bool = false | |
/* ################################################################## */ | |
/** | |
The animation period, in seconds. | |
*/ | |
private var _animationPeriod: TimeInterval = 0.5 | |
/* ################################################################## */ | |
/** | |
This is the "public face" of the duration of our transition, in seconds. | |
- parameter using: The context (ignored). | |
- returns: The time interval for the transition, in seconds. | |
*/ | |
public func transitionDuration(using: UIViewControllerContextTransitioning?) -> TimeInterval { _animationPeriod } | |
/* ################################################################## */ | |
/** | |
This actually performs the fade animation. | |
- parameter using: The transition context, which we mine for "to" and "from" view controllers. | |
*/ | |
public func animateTransition(using inContext: UIViewControllerContextTransitioning) { | |
guard let fromView = inContext.view(forKey: .from), | |
let toView = inContext.view(forKey: .to) | |
else { return } | |
let container = inContext.containerView | |
if _presenting { | |
container.addSubview(toView) | |
toView.alpha = 0.0 | |
} else { | |
container.insertSubview(toView, belowSubview: fromView) | |
} | |
UIView.animate(withDuration: transitionDuration(using: inContext), animations: { [weak self] in | |
if self?._presenting ?? false { | |
toView.alpha = 1.0 | |
} else { | |
fromView.alpha = 0.0 | |
} | |
}, completion: { _ in | |
let success = !inContext.transitionWasCancelled | |
if !success { | |
toView.removeFromSuperview() | |
} | |
inContext.completeTransition(success) | |
}) | |
} | |
/* ################################################################## */ | |
/** | |
The initializer. | |
- parameter presenting: True, if the operation is a "push." | |
- parameter animationPeriodInSeconds: The animation period, in seconds. This is optional. If not provided, the period is half a second. | |
*/ | |
public init(presenting inPresenting: Bool, animationPeriodInSeconds inAnimationPeriod: TimeInterval! = nil) { | |
_presenting = inPresenting | |
guard let animationPeriod = inAnimationPeriod else { return } | |
_animationPeriod = animationPeriod | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment