1

I'm using presentModalView controller and pushing the transition to new view via its controller. And I'm using following code to do the transition (which is working fine)

    [self presentModalViewController:myViewController animated:NO];
CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[myViewController.view layer] addAnimation:animation forKey:@"SwitchToView"];  

but the problem is that, its showing blank white screen and then transition starts. How to avoid this?

Satyam
  • 15,493
  • 31
  • 131
  • 244

3 Answers3

4

first add animation then present

CATransition *animation = [CATransition animation];
[animation setDuration:0.5];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
[[myViewController.view layer] addAnimation:animation forKey:@"SwitchToView"];  


[self presentModalViewController:myViewController animated:NO];
  • 1
    When I did that way, the view is coming from bottom right corner. But I want to have similar one as that of navigation controller. (But I don't have navigation controller in my app and we don't want to implement that) – Satyam Jul 30 '11 at 17:12
  • For me it appears from right to left but still with the white background :-( – Stelian Iancu Dec 13 '11 at 10:57
  • I was using this technique when presenting a `MFMailComposeViewController`, however it stopped working correctly at some point, perhaps iOS6. You can see it in the simulator, a duplicate of the starting view slides right-to-left, and then finally the new view just appears. I've tried with `controller.view.layer`, `controller.view.superview.layer`, and `controller.view.window.layer` and same thing. I wonder if this is a general problem or something weird with my app, either way I'm giving up on the custom transition. – Pierre Houston Sep 30 '13 at 23:55
2

As this wasn't answered, I'll post what worked for me, to allow future seekers to find something useful:

I was trying to display a view in a different XIB file with a CATransition and always got a black screen at the beginning.

The solution was to replace these lines

[[myViewController.view layer];
addAnimation:animation forKey:@"SwitchToView"];

with

[[self.view.superview layer] addAnimation:animation forKey:@"SwitchToView"];

After finding the issue, it was quite easy to understand, because obviously the local window is the one you want to "push".

Perception
  • 79,279
  • 19
  • 185
  • 195
0

I think, uiviewcontroller.transitioningDelegate is the way to do it on iOS7 ans 8 :

//Mark : Custom Transitionning for modal
func presentViewController(viewControllerToPresent: UIViewController, animated flag: Bool, fromRight:Bool , completion: (() -> Void)?) {
    if fromRight
    {
        viewControllerToPresent.modalPresentationStyle = UIModalPresentationStyle.FullScreen
        viewControllerToPresent.transitioningDelegate = self;
        self.presentViewController(viewControllerToPresent, animated: true, completion: completion);
    }
    else
    {
        self.presentViewController(viewControllerToPresent, animated: true, completion: completion)
    }
}


//MARK : Transitioning Delegate
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return self;
}

func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return self;
}

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

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
    let toView = toViewController.viewForTransitionContext(transitionContext)
    let fromView = fromViewController.viewForTransitionContext(transitionContext)
    let containerView = transitionContext.containerView()
    let duration = self.transitionDuration(transitionContext);

    let initialFrame = transitionContext.initialFrameForViewController(fromViewController)
    var offsetRect = initialFrame
    offsetRect.origin.x += CGRectGetWidth(initialFrame);

    //Present
    if toViewController.isBeingPresented()
    {
        // init state before animation
        toView.frame = offsetRect;
        containerView.addSubview(toView);
        // then animate
        UIView.animateWithDuration(duration, animations: { () -> Void in
            toView.frame = initialFrame;
            }, completion: { (finished) -> Void in
                transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
        })

    }
    //Dismiss
    else
    {
        // init state before animation
        containerView.addSubview(toView)
        containerView.sendSubviewToBack(toView)
        // then animate
        UIView.animateWithDuration(duration, animations: { () -> Void in
            fromView.frame = offsetRect
            }, completion: { (finished) -> Void in
                fromView.removeFromSuperview()
                transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
        })
    }
}
Vassily
  • 899
  • 2
  • 8
  • 19