Voltear entre dos ViewControllers bajo el mismo control de navigation

Me referí a esta pregunta y varias preguntas sobre la transición del controller view / view, pero aún no pude encontrar una respuesta satisdate. La mayoría de las soluciones sugieren voltear las vistas en lugar de los controlleres de vista. Sin embargo, los dos controlleres de vista en mi aplicación tienen una lógica de implementación y operación totalmente diferente, por lo tanto, estoy evitando mezclarlos.

En mi aplicación, tengo un controller de vista modal FrontViewController que está embedded en un NavigationController. Después de presionar un button en la vista, el controller de vista modal debe voltear a BackViewController , y viceversa. Alguna vez había probado lo siguiente en FrontViewController :

 let navi = UINavigationController(rootViewController: backController) navi.modalPresentationStyle = .CurrentContext navi.modalTransitionStyle = .FlipHorizontal self.presentViewController(backController, animated: true, completion: nil) 

Esto funciona casi como lo que quiero, excepto que también voltea la barra de navigation. Además, si rechazo la vista modal, solo se desestima el controller de vista en la parte superior de la stack, mientras que no logré que el controller padre / presentador correcto deseche todos los demás controlleres de stack en la vista modal.

Por lo tanto, traté de evitar la stack viewcontroller y uso transitionFromViewController en FrontViewController usando el mismo controller de navigation:

 self.navigationController!.addChildViewController(backController) self.willMoveToParentViewController(nil) self.navigationController!.transitionFromViewController(self, toViewController: backViewController, duration: 1, options: .TransitionFlipFromLeft, animations: {}, completion: ({Bool -> Void in self.removeFromParentController() c.didMoveToParentViewController(self) })) 

Entonces obtuve este error de time de ejecución en la ejecución: el Parent view controller is using legacy containment in call to -[UIViewController transitionFromViewController:toViewController: duration:options:animations:completion:]

Entonces, ¿cómo hacer la transición entre dos controlleres de vista y evitar que permanezcan en la stack del controller de vista?

Puede agregar una transición personalizada a la capa de controlleres de navigation justo antes de presionar el controller de vista.

 let transition = CATransition() transition.duration = 0.3 transition.type = "flip" transition.subtype = kCATransitionFromLeft self.navigationController?.view.layer.addAnimation(transition, forKey: kCATransition) self.navigationController?.pushViewController(viewController!, animated: false) 

Tenga en count que el parámetro animated debe ser false . De lo contrario, tendrá lugar la animation deslizante pnetworkingeterminada.

Vea esta demostración para usted:

Código Swift para flipAnimation:

 let mainStory = UIStoryboard(name: "Main", bundle: nil) let search = mainStory.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController UIView.beginAnimations("animation", context: nil) UIView.setAnimationDuration(1.0) self.navigationController!.pushViewController(search, animated: false) UIView.setAnimationTransition(UIViewAnimationTransition.FlipFromLeft, forView: self.navigationController!.view, cache: false) UIView.commitAnimations() 

Animación FlipViewController

Salida:

introduzca la descripción de la imagen aquí

Swift 3.0 + Debe usar el bloque de animation de UIView , asegúrese de que su viewController en UINavigationController astack:

 let viewController = ViewController(nibName: "xxx", bundle: nil) UIView.transition(with: self.navigationController!.view, duration: 1.0, options: .transitionFlipFromLeft, animations: { self.navigationController?.pushViewController(viewController, animated: false) }, completion: nil) 

aquí el estudiante es NSObjectClass

 var Arraydata:[Student] = [] func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let arr = Arraydata[indexPath.row] if indexPath.row == arr { let story = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController UIView.beginAnimations("", context: nil) UIView.setAnimationDuration(1.0) UIView.setAnimationCurve(UIViewAnimationCurve.easeInOut) UIView.setAnimationTransition(UIViewAnimationTransition.flipFromRight, for: (self.navigationController?.view)!, cache: false) self.navigationController?.pushViewController(story, animated: true) UIView.commitAnimations() } }