How to Push Two View Controllers But Animate Transition Only for the Second One

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

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

How to push multiple view controllers into UINavigation but only show animation once?

Try to use

[a setViewControllers:@[view11, view22] animated:YES];

Hope this would be help to you :)

Exactly, view11 will not be loaded before you pop out view22.

How to show two view controllers as modal but animate transition only for the second one?

Here will be the hierarchy
First VC presents second VC

let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondVC") as! SecondVC
present(vc, animated: true, completion: nil)
present(vc, animated: true, completion: nil)

second VC will add third VC as subview and make it visible

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.

let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ThirdVC") as! ThirdVC
self.addChild(vc)
self.view.addSubview(vc.view)
}

when dismiss third VC remove it from super view with animation and reveal second VC

UIView.animate(withDuration: 0.5, animations: { [weak self] in
self?.view.frame = CGRect(x: 0, y: self?.view.frame.height ?? 0.0, width: self?.view.frame.width ?? 0.0, height: self?.view.frame.height ?? 0.0)
}, completion: { [weak self] _ in
self?.view.removeFromSuperview()
})

dismiss second VC and reveal first VC

dismiss(animated: true, completion: nil)

Present 2 viewcontrollers but only one transition

I finally ended up doing a mix with these two:

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

    NSMutableArray *controllers = [self.navigationController.viewControllers mutableCopy];
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

    MyCViewController *vcC = [storyboard instantiateViewControllerWithIdentifier:IDENTIFIER_VC];
    MyBViewController *vcB = [storyboard instantiateViewControllerWithIdentifier:IDENTIFIER_VC];

    [controllers addObject:vcC];
    [controllers addObject:vcB];

    self.navigationController.delegate = vcB;
    [self.navigationController setViewControllers:controllers animated:YES];
  • https://www.objc.io/issues/5-ios7/view-controller-transitions/

In vcB:

    -(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
if (operation == UINavigationControllerOperationPush || operation == UINavigationControllerOperationPop) {
MyAnimator *animator = [[MyAnimator alloc] init];
animator.presenting = (operation == UINavigationControllerOperationPush);
return animator;
}
return nil;
}

In MyAnimator.m:

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
return 0.4;
}

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

[[transitionContext containerView] addSubview:toViewController.view];

CGRect currentFrame = toViewController.view.frame;
CGRect toFrameInitial = self.presenting ? CGRectOffset(currentFrame, 0, CGRectGetHeight(currentFrame)) : CGRectOffset(currentFrame, 0, -CGRectGetHeight(currentFrame));
CGRect fromFrameFinal = self.presenting ? CGRectOffset(currentFrame, 0, -CGRectGetHeight(currentFrame)) : CGRectOffset(currentFrame, 0, CGRectGetHeight(currentFrame));

toViewController.view.frame = toFrameInitial;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.frame = currentFrame;
fromViewController.view.frame = fromFrameFinal;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}

Flip between two ViewControllers under the same NavigationController

You can add custom transition to the navigation controllers layer just before pushing the view controller.

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)

Note that the animated parameter should be false. Otherwise the default sliding animation will takes place



Related Topics



Leave a reply



Submit