How to push two view controllers but animate transition only for the second one?

To preserve the standard animation for pushing a view controller, in Swift:

let pushVC = UIViewController()
let backVC = UIViewController()

if let navigationController = navigationController {

  navigationController.pushViewController(pushVC, animated: true)

  let stackCount = navigationController.viewControllers.count
  let addIndex = stackCount - 1
  navigationController.viewControllers.insert(backVC, atIndex: addIndex)

}

This displays pushVC normally and inserts backVC into the navigation stack, preserving both the animation and the history for the UINavigationController.

You can use setViewControllers, but you'll lose the standard push animation.


extension UINavigationController {
    open func pushViewControllers(_ inViewControllers: [UIViewController], animated: Bool) {
        var stack = self.viewControllers
        stack.append(contentsOf: inViewControllers)
        self.setViewControllers(stack, animated: animated)
    }
}

Swift Version From KimAMartinsen Solution

guard var controllers = self.navigationController?.viewControllers else {
   return
}

guard let firstVC = self.storyboard?.instantiateViewController(withIdentifier: "Tests") as? firstViewController else { 
   return
}

guard let secondVC = self.storyboard?.instantiateViewController(withIdentifier: "Dashboard") as? SecondViewController else {
    return
}

controllers.append(firstVC)
controllers.append(secondVC)
self.navigationController?.setViewControllers(controllers, animated: true)

The solution you're looking for if you're in the firstVC:

NSMutableArray *controllers = [self.navigationController.viewControllers mutableCopy];
[controllers addObject:secondVc];
[controllers addObject:thirdVC];
[self.navigationController setViewControllers:controllers animated:YES];

This will animate in the thirdVC without the secondVc becoming visible in the process. When the user press the back button, they will return to the secondVc