example custom bar ios swift uiviewcontroller uinavigationcontroller uiviewanimationtransition

ios - custom - Voltear entre dos ViewControllers bajo el mismo NavigationController



navigation controller swift 4 example (5)

Me he referido a esta pregunta y a varias preguntas sobre la transición del controlador de vista / vista, pero todavía no he podido encontrar una respuesta satisfactoria. La mayoría de las soluciones sugieren voltear las vistas en lugar de ver los controladores. Sin embargo, los dos controladores de vista en mi aplicación tienen una lógica de operación e implementación totalmente diferente, por lo que evito mezclarlos.

En mi aplicación, tengo un controlador de vista modal FrontViewController que está incrustado en un NavigationController. Después de presionar un botón en la vista, el controlador de vista modal debe BackViewController a BackViewController , y viceversa. Alguna vez intenté 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 invierte la barra de navegación. Además, si dejo de lado la vista modal, solo se descarta el controlador de vista en la parte superior de la pila, mientras que no pude obtener el controlador padre / presentador correcto para descartar todos los demás controladores de pila en la vista modal.

Por lo tanto, intenté evitar la pila viewcontroller y usar transitionFromViewController en FrontViewController usando el mismo controlador de navegación:

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) }))

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

Entonces, ¿cómo la transición entre dos controladores de vista a la vez que los impide permanecer en la pila del controlador de vista?


Puede agregar una transición personalizada a la capa de controles de navegación justo antes de presionar el controlador 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 cuenta que el parámetro animated debe ser false . De lo contrario, se realizará la animación deslizante predeterminada


Vea esta demostración para usted:

Swift code for 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:


Swift 3.0 + Si utiliza el bloque de animación de UIView , asegúrese de que su viewController en UINavigationController apila:

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() } }


override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(true) // for back button changeTransition() } //btnMap.addTarget(self, action: #selector(searchHotelsResultVC.goToMap), for: .touchUpInside) //btnMap.addTarget(self, action: #selector(MapViewController.backToList), for: .touchUpInside) func goToMap() { // for pushing changeTransition() navigationController?.pushViewController(settingsVC, animated: false) } func backToList() { // for dismiss changeTransition() navigationController?.popViewController(animated: false) dismiss(animated: true, completion: nil) } func changeTransition() { let transition = CATransition() transition.duration = 0.5 transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) //transition.type = kCATransitionPush transition.type = "flip" transition.subtype = kCATransitionFromLeft navigationController?.view.layer.add(transition, forKey: kCATransition) }