In my work on an iOS multi-screen App, I am trying to get my first custom animated transaction to work. Instead of using standard animations when presenting a screen modal and fullscreen, I want to have a horizontal slide in animation.
I have made this work by overriding perform
in UIStoryboardSegue, and make the animation and transaction be performed from here.
Overall, it works, except from one case, which is when a navigation controller embeds a view.
In that case, I have followed a tutorial showing precisely how custom transaction is achieved by implementing the UINavigationControllerDelegate protocol for the particular navigation controller.
import Foundation
import UIKit
class AnimatedNavigationController: UINavigationController, UINavigationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
delegate = self
}
func navigationController(_ navigationController: UINavigationController,
animationControllerFor operation: UINavigationController.Operation,
from fromVC: UIViewController,
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return NavigationControllerTransition()
}
}
Unfortunately the delegate, which should return an animation object:
navigationController(_:animationControllerFor:from:to:)
is never called, and that is my primary problem.
In the tutorial mentioned, a button is used to perform a call to the navigation controller that pushes the destination view with animation set to true:
navigationController.pushViewController(view, animated:true)
In my case, I suspect that the problem is that the navigation controller pushes the view without having the animation parameter set to true, and that explains why the transaction delegate is never called.
(a confirmation off this theory will of course help a bit).
Consequently, I have tried to implement a custom segue that presents the view by calling the push function with animation set to true.
Sadly, I have not been able to get this to work.
When the navigationController.pushViewController(view, animated:true)
is called, it raises an exception saying that view has already been pushed.
I have tried a lot without any luck. Code looks like this:
class NavigationControllerSegue: UIStoryboardSegue {
override func perform() {
let navigationController = self.destination as! UINavigationController
let view = navigationController.viewControllers.first!
navigationController.pushViewController(view, animated: true)
}
}