Forum Xamarin.iOS

How to present a view controller in background by sliding off the current one?

I implemented right to left transition by using this class:

internal class RightToLeftTransitionAnimator : UIViewControllerAnimatedTransitioning
{
    public RightToLeftTransitionAnimator()
    {
    }

    public override double TransitionDuration(IUIViewControllerContextTransitioning transitionContext)
    {
        return 0.35;
    }

    public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
    {
        var inView = transitionContext.ContainerView;
        var toVC = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
        var toView = toVC.View;

        inView.AddSubview(toView);

        var frame = toView.Frame;
        toView.Frame = new CGRect(frame.Width, 0, frame.Width, frame.Height);

        UIView.Animate(TransitionDuration(transitionContext), () => {
            toView.Frame = new CGRect(0, 0, frame.Width, frame.Height);
        }, () => {
            transitionContext.CompleteTransition(true);
        });
    }
}

And now I need to do the opposite when the user presses a back button, moving the current view controller to the right, off screen, to reveal the new one in the background.
The fact is though that the new view controller appears in the foreground, so it is just shown instantly.

Otherwise this is the code for the left to right animation:

var inView = transitionContext.ContainerView;
var fromVC = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
var toVC = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);            
var fromView = fromVC.View;
var toView = toVC.View;

inView.AddSubview(toView);

var frame = toView.Frame;
toView.Frame = new CGRect(0, 0, frame.Width, frame.Height);

UIView.Animate(TransitionDuration(transitionContext), () => {
    fromView.Frame = new CGRect(frame.Width, 0, frame.Width, frame.Height);
}, () => {
     transitionContext.CompleteTransition(true);
});

Best Answer

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    Put the view below the existed presented view when dismissing like:

    public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
    {
        var inView = transitionContext.ContainerView;
        var fromVC = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
        var toVC = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
        var fromView = fromVC.View;
        var toView = toVC.View;
    
        inView.InsertSubview(toView, 0);
    
        var frame = toView.Frame;
        toView.Frame = new CGRect(0, 0, frame.Width, frame.Height);
    
        UIView.Animate(TransitionDuration(transitionContext), () => {
            fromView.Frame = new CGRect(frame.Width, 0, frame.Width, frame.Height);
        }, () => {
            transitionContext.CompleteTransition(true);
        });
    }
    
  • fodorbalintfodorbalint Member ✭✭

    Hi LandLu,

    As a console output shows, inView.Subviews.Length is 0 before adding toView, fromView is not part of its view hierarchy.
    (I had tried inView.InsertSubviewBelow(toView, fromView); before posting this question, which just does the same as AddSubview without throwing error.)
    I might need to end up moving both views without any overlaps.

  • fodorbalintfodorbalint Member ✭✭

    It works indeed!

    Turns out, the line that makes a difference is
    viewController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
    and I used UIModalPresentationStyle.Custom;

    Changing it in your sample will still play the animation, but the screen goes black afterwards.
    I, on the other hand just experienced no animation, because I called PresentViewController() every time instead of making use of DismissViewController().
    But it is a good idea, I didn't know about it.

    Microsoft should update their docs. I followed this guide:
    https://docs.microsoft.com/en-us/xamarin/ios/user-interface/ios-ui/view-controllers/transitions

    @LandLu said:
    I attached my sample here. It worked on iOS 13.3:

Sign In or Register to comment.