Last active
September 28, 2018 02:29
-
-
Save shial4/4e5bfb5fb90f5e784cb3953e15c73edb to your computer and use it in GitHub Desktop.
Simple yet elegant push transition from the rect and back to the same rect.
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
// | |
// PushFromItemAnimator.swift | |
// Between | |
// | |
// Created by Shial on 11/9/18. | |
// Copyright © 2018 Szymon Lorenz Solutions. All rights reserved. | |
// | |
import UIKit | |
class PushFromItemAnimator: NSObject, UIViewControllerAnimatedTransitioning { | |
var duration: TimeInterval | |
var isPresenting: Bool | |
var rect: CGRect? | |
init(duration: TimeInterval, rect: CGRect?, isPresenting: Bool) { | |
self.isPresenting = isPresenting | |
self.duration = duration | |
self.rect = rect | |
} | |
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { | |
let container = transitionContext.containerView | |
guard let fromView = transitionContext.view(forKey: .from) else { | |
transitionContext.completeTransition(false) | |
return | |
} | |
guard let toView = transitionContext.view(forKey: .to) else { | |
transitionContext.completeTransition(false) | |
return | |
} | |
let tabBar = transitionContext.viewController(forKey: .to)?.tabBarController?.tabBar | |
let tabBarHeight = tabBar?.frame.height ?? 0 | |
let tabBarWidth = tabBar?.frame.width ?? 0 | |
if self.isPresenting { | |
container.addSubview(toView) | |
toView.transform = transform(from: toView, | |
to: (self.rect ?? container.bounds).offsetBy(dx: 0, dy: tabBarHeight), | |
in: container) | |
tabBar?.transform = .identity | |
} else { | |
container.insertSubview(toView, belowSubview: fromView) | |
tabBar?.transform = CGAffineTransform(translationX: tabBarWidth, y: tabBarHeight) | |
} | |
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { | |
if self.isPresenting { | |
tabBar?.transform = CGAffineTransform(translationX: tabBarWidth, y: tabBarHeight) | |
toView.transform = .identity | |
} else { | |
tabBar?.transform = .identity | |
fromView.transform = self.transform(from: fromView, | |
to: (self.rect ?? container.bounds).offsetBy(dx: 0, dy: tabBarHeight), | |
in: container) | |
fromView.alpha = 0 | |
} | |
}) { finished in | |
tabBar?.transform = .identity | |
transitionContext.completeTransition(!transitionContext.transitionWasCancelled) | |
} | |
} | |
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { | |
return duration | |
} | |
func transform(from source: UIView, to destination: CGRect, in view: UIView) -> CGAffineTransform { | |
let destinationRect = view.convert(destination, to: view) | |
let sourceRect = source.convert(source.frame, to: view) | |
return CGAffineTransform.identity | |
.translatedBy(x: destinationRect.midX - sourceRect.midX, y: destinationRect.midY - sourceRect.midY) | |
.scaledBy(x: destination.width / source.frame.width, y: destination.height / source.frame.height) | |
} | |
} |
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
extension YourPushedViewController: UINavigationControllerDelegate { | |
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
switch operation { | |
case .push: | |
return PushFromItemAnimator(duration: TimeInterval(0.35), rect: rect, isPresenting: true) | |
default: | |
return PushFromItemAnimator(duration: TimeInterval(UINavigationControllerHideShowBarDuration), rect: rect, isPresenting: false) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Custom push animation
Simple yet elegant push transition from the rect and back to the same rect.
Important
Remember to assign
UINavigationControllerDelegate
toYourPushedViewController
so it can use custom transition coordinator.Example