Commit 9ee829f1 by Daniel Dahan

development: updated MotionTransition delegation and animator

parent f4a5cc8c
......@@ -31,9 +31,6 @@
import UIKit
open class BottomNavigationController: UITabBarController, UITabBarControllerDelegate {
/// The transition animation to use when selecting a new tab.
open var motionTransition = MotionTransition.fade
/**
An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance.
......@@ -119,7 +116,7 @@ open class BottomNavigationController: UITabBarController, UITabBarControllerDel
/// Handles transitions when tabBarItems are pressed.
open func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return .fade == motionTransition ? FadeMotionTransition() : nil
return FadeMotionTransition()
}
/// Prepares the tabBar.
......
......@@ -191,7 +191,7 @@ open class Button: UIButton, Pulseable {
let p = point ?? center
pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in
Motion.delay(0.35) { [weak self] in
self?.pulse.contract()
}
}
......
......@@ -243,7 +243,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable {
let p = point ?? center
pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in
Motion.delay(0.35) { [weak self] in
self?.pulse.contract()
}
}
......
......@@ -201,7 +201,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable {
let p = point ?? center
pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in
Motion.delay(0.35) { [weak self] in
self?.pulse.contract()
}
}
......
......@@ -95,7 +95,7 @@ public struct Motion {
the animations have completed.
*/
@discardableResult
public static func delay(time: TimeInterval, execute block: @escaping () -> Void) -> MotionDelayCancelBlock? {
public static func delay(_ time: TimeInterval, execute block: @escaping () -> Void) -> MotionDelayCancelBlock? {
func asyncAfter(completion: @escaping () -> Void) {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time, execute: completion)
......@@ -179,7 +179,7 @@ public struct Motion {
the animations have completed.
*/
public static func animate(delay time: CFTimeInterval, duration: CFTimeInterval, animations: @escaping (() -> Void), completion: (() -> Void)? = nil) {
delay(time: time) {
delay(time) {
animate(duration: duration, animations: animations, completion: completion)
}
}
......
......@@ -168,7 +168,7 @@ extension CALayer {
}
}
Motion.delay(time: t) { [weak self] in
Motion.delay(t) { [weak self] in
guard let s = self else {
return
}
......
......@@ -30,67 +30,176 @@
import UIKit
/// A memory reference to the MotionIdentifier instance for UIView extensions.
fileprivate var MotionIdentifierKey: UInt8 = 0
fileprivate var MotionTransitionItemKey: UInt8 = 0
fileprivate var MotionTransitionItemControllerKey: UInt8 = 0
fileprivate struct MotionTransitionItem {
fileprivate var identifier: String
fileprivate var animations: [MotionAnimation]
}
fileprivate struct MotionTransitionItemController {
fileprivate var delegate: MotionTransitionDelegate
}
extension UIViewController {
// override func transition(from fromViewController: UIViewController, to toViewController: UIViewController, duration: TimeInterval, options: UIViewAnimationOptions = [], animations: (() -> Void)?, completion: ((Bool) -> Void)? = nil) {
//
// }
/// MaterialLayer Reference.
fileprivate var motionTransition: MotionTransitionItemController {
get {
return AssociatedObject(base: self, key: &MotionTransitionItemControllerKey) {
return MotionTransitionItemController(delegate: MotionTransitionDelegate())
}
}
set(value) {
AssociateObject(base: self, key: &MotionTransitionItemControllerKey, value: value)
}
}
open var transitionDelegate: MotionTransitionDelegate {
return motionTransition.delegate
}
}
extension UIView {
/// MaterialLayer Reference.
fileprivate var motionTransitionItem: MotionTransitionItem {
fileprivate var motionTransition: MotionTransitionItem {
get {
return AssociatedObject(base: self, key: &MotionIdentifierKey) {
return AssociatedObject(base: self, key: &MotionTransitionItemKey) {
return MotionTransitionItem(identifier: "", animations: [])
}
}
set(value) {
AssociateObject(base: self, key: &MotionIdentifierKey, value: value)
AssociateObject(base: self, key: &MotionTransitionItemKey, value: value)
}
}
open var motionIdentifier: String {
open var transitionIdentifier: String {
get {
return motionTransitionItem.identifier
return motionTransition.identifier
}
set(value) {
motionTransitionItem.identifier = value
motionTransition.identifier = value
}
}
open var motionAnimations: [MotionAnimation] {
open var transitionAnimations: [MotionAnimation] {
get {
return motionTransitionItem.animations
return motionTransition.animations
}
set(value) {
motionTransitionItem.animations = value
motionTransition.animations = value
}
}
}
@objc(MotionTransition)
public enum MotionTransition: Int {
case none
case fade
open class MotionTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
}
public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.25
}
}
open class MotionTransitionInteractiveAnimator: NSObject, UIViewControllerInteractiveTransitioning {
public func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) {
}
}
open class MotionTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {
open class MotionTransitionDelegate: NSObject {
open var isPresenting = false
open var containerView: UIView!
open var toView: UIView!
open var toViewController: UIViewController!
open var toViewStartFrame: CGRect!
open var toViewFinalFrame: CGRect!
open var fromView: UIView!
open var fromViewController: UIViewController!
open var fromViewFinalFrame: CGRect!
open func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let tView = transitionContext.view(forKey: .to) else {
return
}
guard let tVC = transitionContext.viewController(forKey: .to) else {
return
}
guard let fView = transitionContext.view(forKey: .from) else {
return
}
guard let fVC = transitionContext.viewController(forKey: .from) else {
return
}
let containerView = transitionContext.containerView
toView = tView
toViewController = tVC
fromView = fView
fromViewController = fVC
toViewStartFrame = transitionContext.initialFrame(for: toViewController)
toViewFinalFrame = transitionContext.finalFrame(for: toViewController)
fromViewFinalFrame = transitionContext.finalFrame(for: fromViewController)
}
open func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.25
}
}
extension MotionTransitionDelegate: UIViewControllerTransitioningDelegate {
open func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return nil
return MotionTransitionAnimator()
}
open func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return nil
return MotionTransitionAnimator()
}
open func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return nil
return MotionTransitionInteractiveAnimator()
}
open func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return nil
return MotionTransitionInteractiveAnimator()
}
}
extension MotionTransitionDelegate: UINavigationControllerDelegate {
open func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresenting = operation == .push
return MotionTransitionAnimator()
}
open func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
return MotionTransitionInteractiveAnimator()
}
}
extension MotionTransitionDelegate: UITabBarControllerDelegate {
// open func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
// return MotionTransitionAnimator()
// }
open func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
isPresenting = true
self.fromViewController = fromViewController ?? fromVC
self.toViewController = toViewController ?? toVC
// self.inContainerController = true
return MotionTransitionAnimator()
}
}
......@@ -110,9 +219,9 @@ open class FadeMotionTransition: NSObject, UIViewControllerAnimatedTransitioning
transitionContext.containerView.addSubview(toView)
UIView.animate(withDuration: transitionDuration(using: transitionContext),
animations: { _ in
toView.alpha = 1
fromView.alpha = 0
animations: { _ in
toView.alpha = 1
fromView.alpha = 0
}) { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
......@@ -123,7 +232,7 @@ open class FadeMotionTransition: NSObject, UIViewControllerAnimatedTransitioning
}
open func animationEnded(_ transitionCompleted: Bool) {
print("FadeMotionTransition ANIMATION ENDED")
print("FadeMotionTransition ANIMATION ENDED")
}
}
......@@ -143,43 +252,53 @@ open class SlideMotionTransition: NSObject, UIViewControllerAnimatedTransitionin
return
}
let duration = transitionDuration(using: nil)
var duration = transitionDuration(using: nil)
switch operation {
case .push:
for n in fromView.subviews {
if 0 < n.motionIdentifier.utf16.count {
for m in toView.subviews {
if n.motionIdentifier == m.motionIdentifier {
m.motion(m.motionAnimations)
if operation == .push {
transitionContext.containerView.addSubview(toView)
for v in toView.subviews {
if 0 < v.transitionIdentifier.utf16.count {
for a in v.transitionAnimations {
switch a {
case let .duration(dur):
if dur > duration {
duration = dur
}
default:break
}
}
v.motion(v.transitionAnimations)
}
}
Motion.delay(time: duration) {
Motion.delay(duration) {
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
if operation == .pop {
transitionContext.containerView.addSubview(fromView)
transitionContext.containerView.addSubview(toView)
case .pop:
for n in fromView.subviews {
if 0 < n.motionIdentifier.utf16.count {
for m in toView.subviews {
if n.motionIdentifier == m.motionIdentifier {
m.motion(m.motionAnimations)
for v in fromView.subviews {
if 0 < v.transitionIdentifier.utf16.count {
for a in v.transitionAnimations {
switch a {
case let .duration(dur):
if dur > duration {
duration = dur
}
default:break
}
}
v.motion(v.transitionAnimations)
}
}
Motion.delay(time: duration) {
Motion.delay(duration) {
transitionContext.containerView.addSubview(toView)
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
transitionContext.containerView.addSubview(toView)
case .none:break
}
}
......@@ -192,6 +311,84 @@ open class SlideMotionTransition: NSObject, UIViewControllerAnimatedTransitionin
}
}
//open class MotionTransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning {
// var presenting = false
//
// open func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
// let containerView = transitionContext.containerView
//
// guard let fromVC = transitionContext.viewController(forKey: .from) else {
// return
// }
//
// guard let toVC = transitionContext.viewController(forKey: .to) else {
// return
// }
//
// guard let fromView = transitionContext.view(forKey: .from) else {
// return
// }
//
// guard let toView = transitionContext.view(forKey: .to) else {
// return
// }
//
// let containerFrame = containerView.frame
// var toViewStartFrame = transitionContext.initialFrame(for: toVC)
// let toViewFinalFrame = transitionContext.finalFrame(for: toVC)
// var fromViewFinalFrame = transitionContext.finalFrame(for: fromVC)
//
// // Set up the animation parameters.
// if (presenting) {
// // Modify the frame of the presented view so that it starts
// // offscreen at the lower-right corner of the container.
// toViewStartFrame.origin.x = containerFrame.size.width;
// toViewStartFrame.origin.y = containerFrame.size.height;
// }
// else {
// // Modify the frame of the dismissed view so it ends in
// // the lower-right corner of the container view.
// fromViewFinalFrame = CGRect(x: containerFrame.size.width,
// y: containerFrame.size.height,
// width: toView.frame.size.width,
// height: toView.frame.size.height);
// }
//
// // Always add the "to" view to the container.
// // And it doesn't hurt to set its start frame.
// containerView.addSubview(toView)
// toView.frame = toViewStartFrame;
//
// UIView.animate(withDuration: transitionDuration(using: nil), animations: { [weak self] in
// guard let s = self else {
// return
// }
//
// if s.presenting {
// toView.frame = toViewFinalFrame
// } else {
// fromView.frame = fromViewFinalFrame
// }
//
// }, completion: { [weak self] _ in
// guard let s = self else {
// return
// }
//
// let success = !transitionContext.transitionWasCancelled
// if (s.presenting && !success) || (!s.presenting && success) {
// toView.removeFromSuperview()
// }
//
// transitionContext.completeTransition(success)
// })
// }
//
// open func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
// return 0.25
// }
//}
//@objc(TransitionMotion)
//public enum TransitionMotion: Int {
......
......@@ -121,7 +121,7 @@ open class NavigationController: UINavigationController {
open func prepare() {
navigationBar.heightPreset = .normal
navigationBar.width = view.width
delegate = self
delegate = transitionDelegate
view.clipsToBounds = true
view.backgroundColor = .white
view.contentScaleFactor = Screen.scale
......@@ -134,12 +134,6 @@ open class NavigationController: UINavigationController {
}
}
extension NavigationController: UINavigationControllerDelegate {
open func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return SlideMotionTransition(operation: operation)
}
}
extension NavigationController: UINavigationBarDelegate {
/**
Delegation method that is called when a new UINavigationItem is about to be pushed.
......
......@@ -156,7 +156,7 @@ extension PulseMotion {
default:break
}
Motion.delay(time: duration) {
Motion.delay(duration) {
bLayer.setValue(true, forKey: "animated")
}
}
......@@ -173,7 +173,7 @@ extension PulseMotion {
return
}
Motion.delay(time: animated ? 0 : 0.15) { [animation = animation, color = color] in
Motion.delay(animated ? 0 : 0.15) { [animation = animation, color = color] in
guard let pLayer = bLayer.sublayers?.first as? CAShapeLayer else {
return
}
......@@ -192,7 +192,7 @@ extension PulseMotion {
default:break
}
Motion.delay(time: duration) {
Motion.delay(duration) {
pLayer.removeFromSuperlayer()
bLayer.removeFromSuperlayer()
}
......
......@@ -75,7 +75,7 @@ open class PulseView: View, Pulseable {
let p = point ?? center
pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in
Motion.delay(0.35) { [weak self] in
self?.pulse.contract()
}
}
......
......@@ -123,7 +123,7 @@ open class SnackbarController: RootController {
*/
@discardableResult
open func animate(snackbar status: SnackbarStatus, delay: TimeInterval = 0, animations: ((Snackbar) -> Void)? = nil, completion: ((Snackbar) -> Void)? = nil) -> MotionDelayCancelBlock? {
return Motion.delay(time: delay) { [weak self, status = status, animations = animations, completion = completion] in
return Motion.delay(delay) { [weak self, status = status, animations = animations, completion = completion] in
guard let s = self else {
return
}
......
......@@ -117,7 +117,7 @@ open class TableViewCell: UITableViewCell, Pulseable {
let p = point ?? center
pulse.expand(point: p)
Motion.delay(time: 0.35) { [weak self] in
Motion.delay(0.35) { [weak self] in
self?.pulse.contract()
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment