I want to achieve smooth animation between views with a different UINavigationBar
background colors. Embedded views have the same background color as UINavigationBar
and I want to mimic push/pop transition animation like:
I've prepared custom transition:
class CustomTransition: NSObject, UIViewControllerAnimatedTransitioning {
private let duration: TimeInterval
private let isPresenting: Bool
init(duration: TimeInterval = 1.0, isPresenting: Bool) {
self.duration = duration
self.isPresenting = isPresenting
}
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
guard
let toVC = transitionContext.viewController(forKey: .to),
let fromVC = transitionContext.viewController(forKey: .from),
let toView = transitionContext.view(forKey: .to),
let fromView = transitionContext.view(forKey: .from)
else {
return
}
let rightTranslation = CGAffineTransform(translationX: container.frame.width, y: 0)
let leftTranslation = CGAffineTransform(translationX: -container.frame.width, y: 0)
toView.transform = isPresenting ? rightTranslation : leftTranslation
container.addSubview(toView)
container.addSubview(fromView)
fromVC.navigationController?.navigationBar.backgroundColor = .clear
fromVC.navigationController?.navigationBar.setBackgroundImage(UIImage.fromColor(color: .clear), for: .default)
UIView.animate(
withDuration: self.duration,
animations: {
fromVC.view.transform = self.isPresenting ? leftTranslation :rightTranslation
toVC.view.transform = .identity
},
completion: { _ in
fromView.transform = .identity
toVC.navigationController?.navigationBar.setBackgroundImage(
UIImage.fromColor(color: self.isPresenting ? .yellow : .lightGray),
for: .default
)
transitionContext.completeTransition(true)
}
)
}
}
And returned it in the UINavigationControllerDelegate
method implementation:
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return CustomTransition(isPresenting: operation == .push)
}
While push animation works pretty well pop doesn't.
Questions:
- Why after clearing NavBar color before pop animation it remains yellow?
- Is there any better way to achieve my goal? (navbar can't just be transparent all the time because it's only a part of the flow)
Here is the link to my test project on GitHub.
EDIT
Here is the gif presenting the full picture of discussed issue and the desired effect: