5

Ich hatte auf this question verwiesen und mehrere Fragen über View/View Controller-Übergang, konnte aber immer noch keine zufriedene Antwort finden. Die meisten Lösungen schlagen vor, die Ansichten anstelle von View-Controllern zu spiegeln. Die beiden View-Controller in meiner App haben jedoch eine völlig andere Betriebs- und Implementierungslogik, sodass ich es vermeide, sie miteinander zu mischen.Flip zwischen zwei ViewControllers unter dem gleichen NavigationController

In meiner App habe ich eine modale Ansicht Controller FrontViewController, die in einem NavigationController eingebettet ist. Nach dem Drücken einer Taste in der Ansicht sollte der Modalansicht-Controller zu BackViewController wechseln und umgekehrt. Ich hatte schon einmal versucht, die folgenden in FrontViewController:

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

Das funktioniert fast wie das, was ich will, außer dass es Navigationsleiste und Flips. Wenn ich die modale Ansicht verwerfe, wird außerdem nur der View-Controller oben auf dem Stack verworfen, während es mir nicht gelang, den richtigen übergeordneten/präsentierenden Controller dazu zu bringen, alle anderen Stack-Controller in der modalen Ansicht zu verwerfen.

So habe ich versucht, weiter Viewcontroller Stapel zu verhindern und stattdessen transitionFromViewController in FrontViewController mit den gleichen Navigation-Controller verwenden:

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

Dann habe ich diesen Laufzeitfehler auf executiing: Parent view controller is using legacy containment in call to -[UIViewController transitionFromViewController:toViewController: duration:options:animations:completion:]

So, wie man Übergang zwischen zwei View-Controllern, während verhindert wird, dass sie im View-Controller-Stack verbleiben?

Antwort

11

Sie können der Ebene der Navigationssteuerungen einen benutzerdefinierten Übergang hinzufügen, bevor Sie den View-Controller drücken.

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) 

Beachten Sie, dass die animated Parameter false sein sollte. Andernfalls wird die Standard Animation Gleiten stattfindet

+0

Diese Lösung ist einfach und funktioniert Wie ein Zauber! Danke vielmals! – whitney13625

8

diese Demo Sehen Sie:

Swift-Code für 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() 

FlipViewController Animation

Ausgang:

enter image description here

+0

Dies ist auch eine gute Lösung, danke! – whitney13625

+0

ja, es ist möglich, auch in Nav nächste Taste ... –

+0

Sorry, ich meinte in Nav-Back-Taste? –

1

Swift 3.0 + Sollte UIView ‚s Animationsblock verwenden, Ihre viewController in UINavigationController Stapel sicher:

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

hier Schüler ist 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() 

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

    }