Individual segue U-turn animation

I have the following setup:

Setup idea

The red controller has a method

- (IBAction)unwindToRed:(UISegue *)segue 

and a

 - (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier 

which returns the user segment for this event.

In my custom segue, the execution code has the following:

 - (void)perform { // Just helpers to get the controllers from the segue UIViewController *destination = self.destinationViewController; UIViewController *source = self.sourceViewController; // Setting transitioning delegate for custom transitions destination.transitioningDelegate = self; source.transitioningDelegate = self; destination.modalTransitionStyle = UIModalPresentationCustom; source.modalPresentationStyle = UIModalPresentationCurrentContext; // When I am transitioning to a new one if(!self.reversed) { [source presentViewController:destination animated:YES completion:nil]; } // Or reversing from a current one else { [source dismissViewControllerAnimated:YES completion:nil]; } } 

As you can see, I have set up a transition delegate, which in turn causes

 - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext 

on the animation controller, where I apply my custom animation. But now, when I click Unwind to Red on the yellow view, it only "unwinds" its parent. (e.g. blue).

When I leave the custom segue out of the equation, it works just fine. It goes the way up.

Now I think this is due to

 [source dismissViewControllerAnimated:YES]; 

since this is usually just a β€œone-up” question, I think I should call it so that it reaches red when it was necessary? Yellow is a modal overlay. So "pop too root" will not work.

+6
source share
3 answers

Defining a custom segment

The solution was to use a special session to unwind. Unfortunately, you cannot specify a custom segue for unwinding in the interface builder, as you can in normal mode. You must specify it with a code.

There is a function on the UIViewController that you can override with called segueForUnwindingToViewController , which indicates which segue to use for unwinding. The hard part is knowing which view controller should override this function. The answer is to do this on the parent view controller that you go to / from. In my case, this is a UINavigationController . The navigation controller is the container controller for the first and third controllers. If I had built-in controllers for child views in my views, then the answer would not be a navigation controller, but a parent view controller.

Create your own navigation controller, inheriting from the UINavigationController . Then, make sure the custom class of your navigation controller is configured in the interface builder. Now you can override the segueForUnwindingToViewController function. Here is a minimal implementation.

 class MyNavigationController: UINavigationController { override func segueForUnwindingToViewController(toViewController: UIViewController, fromViewController: UIViewController, identifier: String?) -> UIStoryboardSegue { return UIStoryboardSegue(identifier: identifier, source: fromViewController, destination: toViewController) } } 

Adding animation to a custom segment

 override func segueForUnwindingToViewController(toViewController: UIViewController, fromViewController: UIViewController, identifier: String?) -> UIStoryboardSegue { return UIStoryboardSegue(identifier: identifier, source: fromViewController, destination: toViewController) { let fromView = fromViewController.view let toView = toViewController.view if let containerView = fromView.superview { let initialFrame = fromView.frame var offscreenRect = initialFrame offscreenRect.origin.x -= CGRectGetWidth(initialFrame) toView.frame = offscreenRect containerView.addSubview(toView) // Being explicit with the types NSTimeInterval and CGFloat are important // otherwise the swift compiler will complain let duration: NSTimeInterval = 1.0 let delay: NSTimeInterval = 0.0 let options = UIViewAnimationOptions.CurveEaseInOut let damping: CGFloat = 0.5 let velocity: CGFloat = 4.0 UIView.animateWithDuration(duration, delay: delay, usingSpringWithDamping: damping, initialSpringVelocity: velocity, options: options, animations: { toView.frame = initialFrame }, completion: { finished in toView.removeFromSuperview() if let navController = toViewController.navigationController { navController.popToViewController(toViewController, animated: false) } }) } } } 

Details from this post

+1
source

You want to use the popToViewController navigation controller:

  [source.navigationController popToViewController:destination animated:YES]; 

or, use animated:NO and put it all in an animation block: for example:

 UIViewAnimationOptions animation = UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowAnimatedContent; UIViewController *source = (UIViewController *) self.sourceViewController; UIViewController *dest = (UIViewController *) self.destinationViewController; [UIView transitionWithView:src.navigationController.view duration:0.4 options: animation animations:^{ [source.navigationController popToViewController:dest animated:NO]; } completion:^(BOOL finished) { }]; 
0
source
  • Check out the implementation of UIStoryboardSegue . Have you used modalTransitionStyle typo in your post or in your actual code? Fixed:

     destination.modalPresentationStyle = UIModalPresentationCustom; 
  • I also had success without writing a custom UIStoryboardSegue . Try to associate the deploy to red button action method with the empty -unwindToRed: method without overriding the -segueForUnwindingToViewController: (for example, CTRL + drag the blue VC "Exit" symbol from IB to the -unwindToRed: and select -unwindToRed: from the list.)

  • If # 2 does not reject the blue VC, you can try calling the following manually in the -unwindToRed: IBAction method:

     [self dismissViewControllerAnimated:NO completion:nil]; 
-1
source

Source: https://habr.com/ru/post/971652/


All Articles