Last active
April 2, 2017 13:27
-
-
Save macbellingrath/08a54ffc08f39c650181688a625d4d7f to your computer and use it in GitHub Desktop.
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 | |
import PlaygroundSupport | |
class FirstTable: UITableViewController, UIViewControllerTransitioningDelegate { | |
lazy var animator = TransitionAnimator() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseID") | |
} | |
override func numberOfSections(in tableView: UITableView) -> Int { | |
return 1 | |
} | |
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return 20 | |
} | |
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseID", for: indexPath) | |
cell.textLabel?.text = "Press Me" | |
return cell | |
} | |
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
let second = SecondTable(style: UITableViewStyle.grouped) | |
second.transitioningDelegate = self | |
present(second, animated: true, completion: nil) | |
} | |
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
animator.isPresenting = true | |
return animator | |
} | |
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
animator.isPresenting = false | |
return animator | |
} | |
} | |
class TransitionAnimator: NSObject, UIViewControllerAnimatedTransitioning { | |
let duration: Double = 1 | |
var isPresenting = true | |
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { | |
return duration | |
} | |
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { | |
if isPresenting { | |
animatePresentation(using: transitionContext) | |
} else { | |
animateDismissal(using: transitionContext) | |
} | |
} | |
func animatePresentation(using transitionContext: UIViewControllerContextTransitioning){ | |
guard let toVC = transitionContext.viewController(forKey: .to) as? UITableViewController else { | |
return | |
} | |
let yTransform: CGFloat = 10 | |
for cell in toVC.tableView.visibleCells{ | |
cell.alpha = 0 | |
cell.transform = cell.transform.translatedBy(x: 0, y: yTransform) | |
} | |
toVC.view.alpha = 0.8 | |
let containerView = transitionContext.containerView | |
containerView.addSubview(toVC.view) | |
let duration = transitionDuration(using: transitionContext) | |
let count = Double(toVC.tableView.indexPathsForVisibleRows?.count ?? 1) | |
let totalDelay = 0.01 * count | |
let individualDelay = totalDelay / count | |
let leftOverTime = duration - totalDelay | |
let individualDuration = leftOverTime / count | |
for (offset, cell) in toVC.tableView.visibleCells | |
.reversed() | |
.enumerated() { | |
UIView.animate(withDuration: individualDuration, delay: individualDelay * Double(offset), usingSpringWithDamping: 0.2, initialSpringVelocity: 10, options: [], animations: { | |
cell.alpha = 1 | |
cell.transform = .identity | |
}, completion: nil) | |
} | |
UIView.animate(withDuration: duration, animations: { | |
toVC.view.alpha = 1 | |
}, completion: { finished in | |
let cancelled = transitionContext.transitionWasCancelled | |
transitionContext.completeTransition(!cancelled) | |
}) | |
} | |
func animateDismissal(using transitionContext: UIViewControllerContextTransitioning){ | |
guard let fromVC = transitionContext.viewController(forKey: .from) as? UITableViewController else { | |
return | |
} | |
let containerView = transitionContext.containerView | |
containerView.addSubview(fromVC.view) | |
let duration = transitionDuration(using: transitionContext) | |
let count = Double(fromVC.tableView.indexPathsForVisibleRows?.count ?? 1) | |
let totalDelay = 0.01 * count | |
let individualDelay = totalDelay / count | |
let leftOverTime = duration - totalDelay | |
let individualDuration = leftOverTime / count | |
for (offset, cell) in fromVC.tableView.visibleCells | |
.reversed() | |
.enumerated() { | |
UIView.animate(withDuration: individualDuration, delay: individualDelay * Double(offset), usingSpringWithDamping: 0.2, initialSpringVelocity: 10, options: [], animations: { | |
cell.alpha = 1 | |
cell.transform = cell.transform.translatedBy(x: 0, y: 100) | |
}, completion: nil) | |
} | |
UIView.animate(withDuration: duration, animations: { | |
fromVC.view.alpha = 0 | |
}, completion: { finished in | |
let cancelled = transitionContext.transitionWasCancelled | |
transitionContext.completeTransition(!cancelled) | |
}) | |
} | |
} | |
class SecondTable: UITableViewController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "reuseID") | |
automaticallyAdjustsScrollViewInsets = false | |
} | |
override func numberOfSections(in tableView: UITableView) -> Int { | |
return 1 | |
} | |
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | |
return 20 | |
} | |
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | |
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseID", for: indexPath) | |
cell.textLabel?.text = "WWDC" | |
return cell | |
} | |
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | |
dismiss(animated: true, completion: nil) | |
} | |
} | |
PlaygroundPage.current.liveView = FirstTable(style: .plain) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment