I created a simple custom transition animation for UIViewController with UIViewControllerAnimatedTransitioning. Everything is working, but when target view presents, content starts appear from bottom right corner and when view is disappear, content disappear from left top corner. I attached gif with example. This is my code:
CustomViewAnimator.swift
class CustomViewAnimator: NSObject, UIViewControllerAnimatedTransitioning {
private let interval = 0.5
var forward = false
var originFrame: CGRect = .zero
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return interval
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let toView = transitionContext.view(forKey: .to) else {return}
guard let fromView = transitionContext.view(forKey: .from) else {return}
let destinationView = forward ? toView : fromView
destinationView.alpha = forward ? 0 : 1
forward ? containerView.addSubview(toView) : containerView.insertSubview(toView, belowSubview: fromView)
forward ? (destinationView.frame = originFrame) : (destinationView.frame = fromView.frame)
UIView.animate(withDuration: interval, animations: {
self.forward ? (destinationView.frame = fromView.frame) : (destinationView.frame = self.originFrame)
destinationView.alpha = self.forward ? 1 : 0
}) { (finished) in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}
}
}
MainViewController.self
class MainViewController: UIViewController {
private var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
@objc private func openView() {
let viewController = TargetViewController()
viewController.transitioningDelegate = self
navigationController?.pushViewController(viewController, animated: true)
}
}
extension MainViewController: UINavigationControllerDelegate {
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let animator = CustomViewAnimator()
animator.originFrame = button.frame
animator.forward = (operation == .push)
return animator
}
}
extension MainViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let animator = CustomViewAnimator()
animator.forward = true
return animator
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let animator = CustomViewAnimator()
animator.forward = false
return animator
}
}
TargetViewController.swift
class TargetViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setup()
}
}
extension TargetViewController {
fileprivate func setup() {
view.backgroundColor = .orange
navigationItem.title = "Target view"
let label: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Hello from target view :)"
label.textColor = .white
label.font = UIFont.boldSystemFont(ofSize: 18)
return label
}()
view.addSubview(label)
label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
}
Can anybody say how I can fix this issue, so label(or any other content) in TargetViewController stayed fixed on their places?
