public async override void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)
		{
			UIViewController fromVC = transitionContext.GetViewControllerForKey (UITransitionContext.FromViewControllerKey);
			UIView fromView = fromVC.View;
			UIViewController toVC = transitionContext.GetViewControllerForKey (UITransitionContext.ToViewControllerKey);
			UIView toView = toVC.View;

			UIView containerView = transitionContext.ContainerView;
			if (IsPresentation)
				containerView.AddSubview (toView);

			UIViewController animatingVC = IsPresentation? toVC : fromVC;
			UIView animatingView = animatingVC.View;

			animatingView.Frame = transitionContext.GetFinalFrameForViewController (animatingVC);

			CGAffineTransform presentedTransform = CGAffineTransform.MakeIdentity ();
			CGAffineTransform dismissedTransform = CGAffineTransform.MakeScale (0.001f, 0.001f) * CGAffineTransform.MakeRotation (8 * (float)Math.PI);

			animatingView.Transform = IsPresentation ? dismissedTransform : presentedTransform;

			var opt = UIViewAnimationOptions.AllowUserInteraction | UIViewAnimationOptions.BeginFromCurrentState;
			await UIView.AnimateNotifyAsync (TransitionDuration (transitionContext), 0, 300, 5, opt, () => {
				animatingView.Transform = IsPresentation ? presentedTransform : dismissedTransform;
			});
			animatingView.Transform = CGAffineTransform.MakeIdentity ();

			if (!IsPresentation)
				fromView.RemoveFromSuperview ();

			transitionContext.CompleteTransition (true);
		}
        public async override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            UIViewController fromVC   = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
            UIView           fromView = fromVC.View;
            UIViewController toVC     = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
            UIView           toView   = toVC.View;

            UIView containerView = transitionContext.ContainerView;

            if (IsPresentation)
            {
                containerView.AddSubview(toView);
            }

            UIViewController animatingVC   = IsPresentation ? toVC : fromVC;
            UIView           animatingView = animatingVC.View;

            CGRect appearedFrame  = transitionContext.GetFinalFrameForViewController(animatingVC);
            CGRect dismissedFrame = appearedFrame;

            CGPoint targetLacation = dismissedFrame.Location;

            targetLacation.X       += dismissedFrame.Size.Width;
            dismissedFrame.Location = targetLacation;

            CGRect initialFrame = IsPresentation ? dismissedFrame : appearedFrame;
            CGRect finalFrame   = IsPresentation ? appearedFrame : dismissedFrame;

            animatingView.Frame = initialFrame;

            UIViewAnimationOptions opt = UIViewAnimationOptions.AllowUserInteraction
                                         | UIViewAnimationOptions.BeginFromCurrentState;
            await UIView.AnimateNotifyAsync(TransitionDuration (transitionContext), 0, 300, 5, opt, () => {
                animatingView.Frame = finalFrame;
            });

            if (!IsPresentation)
            {
                fromView.RemoveFromSuperview();
            }

            transitionContext.CompleteTransition(true);
        }
        void SetUpTransitionContainerHierarchy(IUIViewControllerContextTransitioning transitionContext)
        {
            var fromView = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
            var toView   = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            var toViewController = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);

            if (toView != null)
            {
                toView.Frame = transitionContext.GetFinalFrameForViewController(toViewController);
            }

            if (toView != null && !toView.IsDescendantOfView(transitionContext.ContainerView))
            {
                transitionContext.ContainerView.AddSubview(toView);
            }

            if (IsDismissing)
            {
                transitionContext.ContainerView.BringSubviewToFront(fromView);
            }
        }
Ejemplo n.º 4
0
        public async override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            UIViewController fromVC   = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
            UIView           fromView = fromVC.View;
            UIViewController toVC     = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
            UIView           toView   = toVC.View;

            UIView containerView = transitionContext.ContainerView;

            if (IsPresentation)
            {
                containerView.AddSubview(toView);
            }

            UIViewController animatingVC   = IsPresentation? toVC : fromVC;
            UIView           animatingView = animatingVC.View;

            animatingView.Frame = transitionContext.GetFinalFrameForViewController(animatingVC);

            CGAffineTransform presentedTransform = CGAffineTransform.MakeIdentity();
            CGAffineTransform dismissedTransform = CGAffineTransform.MakeScale(0.001f, 0.001f) * CGAffineTransform.MakeRotation(8 * (float)Math.PI);

            animatingView.Transform = IsPresentation ? dismissedTransform : presentedTransform;

            var opt = UIViewAnimationOptions.AllowUserInteraction | UIViewAnimationOptions.BeginFromCurrentState;
            await UIView.AnimateNotifyAsync(TransitionDuration (transitionContext), 0, 300, 5, opt, () => {
                animatingView.Transform = IsPresentation ? presentedTransform : dismissedTransform;
            });

            animatingView.Transform = CGAffineTransform.MakeIdentity();

            if (!IsPresentation)
            {
                fromView.RemoveFromSuperview();
            }

            transitionContext.CompleteTransition(true);
        }
		public async override void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)
		{
			UIViewController fromVC = transitionContext.GetViewControllerForKey (UITransitionContext.FromViewControllerKey);
			UIView fromView = fromVC.View;
			UIViewController toVC = transitionContext.GetViewControllerForKey (UITransitionContext.ToViewControllerKey);
			UIView toView = toVC.View;

			UIView containerView = transitionContext.ContainerView;

			if (IsPresentation)
				containerView.AddSubview (toView);

			UIViewController animatingVC = IsPresentation ? toVC : fromVC;
			UIView animatingView = animatingVC.View;

			CGRect appearedFrame = transitionContext.GetFinalFrameForViewController (animatingVC);
			CGRect dismissedFrame = appearedFrame;

			CGPoint targetLacation = dismissedFrame.Location;
			targetLacation.X += dismissedFrame.Size.Width;
			dismissedFrame.Location = targetLacation;

			CGRect initialFrame = IsPresentation ? dismissedFrame : appearedFrame;
			CGRect finalFrame = IsPresentation ? appearedFrame : dismissedFrame;

			animatingView.Frame = initialFrame;

			UIViewAnimationOptions opt = UIViewAnimationOptions.AllowUserInteraction
				                       | UIViewAnimationOptions.BeginFromCurrentState;
			await UIView.AnimateNotifyAsync (TransitionDuration (transitionContext), 0, 300, 5, opt, () => {
				animatingView.Frame = finalFrame;
			});

			if (!IsPresentation)
				fromView.RemoveFromSuperview ();

			transitionContext.CompleteTransition (true);
		}
Ejemplo n.º 6
0
            public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
            {
                var toController   = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
                var fromController = (DurationChangeViewController)transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
                var container      = transitionContext.ContainerView;

                toController.View.Frame = transitionContext.GetFinalFrameForViewController(toController);
                container.InsertSubviewBelow(toController.View, fromController.View);
                fromController.View.Alpha = 1;

                UIView.Animate(
                    TransitionDuration(transitionContext),
                    delegate {
                    fromController.View.Alpha = 0;
                },
                    delegate {
                    if (!transitionContext.TransitionWasCancelled)
                    {
                        fromController.View.RemoveFromSuperview();
                    }
                    transitionContext.CompleteTransition(!transitionContext.TransitionWasCancelled);
                }
                    );
            }
            public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
            {
                var toController   = (DurationChangeViewController)transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
                var fromController = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
                var container      = transitionContext.ContainerView;

                var imageView = (UIImageView)toController.View;

                imageView.Image = GetBlurred(fromController.View);

                toController.View.Frame = transitionContext.GetFinalFrameForViewController(toController);
                toController.View.Alpha = 0;
                container.InsertSubviewAbove(toController.View, fromController.View);

                UIView.Animate(TransitionDuration(transitionContext)
                               , () => toController.View.Alpha = 1
                               , () => {
                    if (!transitionContext.TransitionWasCancelled)
                    {
                        fromController.View.RemoveFromSuperview();
                    }
                    transitionContext.CompleteTransition(!transitionContext.TransitionWasCancelled);
                });
            }
            public override void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)
            {
                var toController = transitionContext.GetViewControllerForKey (UITransitionContext.ToViewControllerKey);
                var fromController = (DurationChangeViewController)transitionContext.GetViewControllerForKey (UITransitionContext.FromViewControllerKey);
                var container = transitionContext.ContainerView;

                toController.View.Frame = transitionContext.GetFinalFrameForViewController (toController);
                container.InsertSubviewBelow (toController.View, fromController.View);
                fromController.View.Alpha = 1;

                UIView.Animate (
                    TransitionDuration (transitionContext),
                delegate {
                    fromController.View.Alpha = 0;
                },
                delegate {
                    if (!transitionContext.TransitionWasCancelled) {
                        fromController.View.RemoveFromSuperview ();
                    }
                    transitionContext.CompleteTransition (!transitionContext.TransitionWasCancelled);
                }
                );
            }
            public override void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)
            {
                var toController = (DurationChangeViewController)transitionContext.GetViewControllerForKey (UITransitionContext.ToViewControllerKey);
                var fromController = transitionContext.GetViewControllerForKey (UITransitionContext.FromViewControllerKey);
                var container = transitionContext.ContainerView;

                var imageView = (UIImageView)toController.View;
                imageView.Image = GetBlurred (fromController.View);

                toController.View.Frame = transitionContext.GetFinalFrameForViewController (toController);
                toController.View.Alpha = 0;
                container.InsertSubviewAbove (toController.View, fromController.View);

                UIView.Animate (TransitionDuration (transitionContext)
                                ,() => toController.View.Alpha = 1
                ,() => {
                    if (!transitionContext.TransitionWasCancelled) {
                        fromController.View.RemoveFromSuperview ();
                    }
                    transitionContext.CompleteTransition (!transitionContext.TransitionWasCancelled);
                });
            }
Ejemplo n.º 10
0
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var    fromViewController = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
            var    toViewController   = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
            UIView containerView      = transitionContext.ContainerView;

            var fromView = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
            var toView   = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            fromView.Frame = transitionContext.GetInitialFrameForViewController(fromViewController);
            toView.Frame   = transitionContext.GetFinalFrameForViewController(toViewController);
            bool isPush = Array.IndexOf(toViewController.NavigationController.ViewControllers, toViewController) > Array.IndexOf(fromViewController.NavigationController.ViewControllers, fromViewController);

            containerView.AddSubview(toView);

            // TODO
            UIImage fromViewSnapshot;
            var     toViewSnapshot = new UIImage();

            UIGraphics.BeginImageContextWithOptions(containerView.Bounds.Size, true, containerView.Window.Screen.Scale);
            fromView.DrawViewHierarchy(containerView.Bounds, false);
            fromViewSnapshot = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();

            CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() => {
                UIGraphics.BeginImageContextWithOptions(containerView.Bounds.Size, true, containerView.Window.Screen.Scale);
                toView.DrawViewHierarchy(containerView.Bounds, false);
                toViewSnapshot = UIGraphics.GetImageFromCurrentImageContext();
                UIGraphics.EndImageContext();
            });

            var transitionContainer = new UIView(containerView.Bounds)
            {
                Opaque          = true,
                BackgroundColor = UIColor.Black
            };

            containerView.AddSubview(transitionContainer);

            CATransform3D t = CATransform3D.Identity;

            t.m34 = 1f / -900f;
            transitionContainer.Layer.SublayerTransform = t;

            // The size and number of slices is a function of the width.
            var sliceSize         = Math.Round(transitionContainer.Frame.Width / 10f);
            var horizontalSileces = Math.Ceiling(transitionContainer.Frame.Width / sliceSize);
            var verticalSlices    = Math.Ceiling(transitionContainer.Frame.Height / sliceSize);

            // transitionSpacing controls the transition duration for each slice.
            // Higher values produce longer animations with multiple slices having
            // their animations 'in flight' simultaneously.
            float transitionSpacing  = 160f;
            var   transitionDuration = TransitionDuration(transitionContext);

            nfloat dx = isPush ? transitionContainer.Bounds.GetMaxY() - transitionContainer.Bounds.GetMinX()
                                                                : transitionContainer.Bounds.GetMinX() - transitionContainer.Bounds.GetMaxX();

            nfloat dy = isPush ? transitionContainer.Bounds.GetMaxY() - transitionContainer.Bounds.GetMinY() :
                        transitionContainer.Bounds.GetMinY() - transitionContainer.Bounds.GetMaxY();

            var transitionVector = new CGVector(dx, dy);

            var transitionVectorLength = (nfloat)Math.Sqrt(transitionVector.dx * transitionVector.dx + transitionVector.dy * transitionVector.dy);
            var transitionUnitVector   = new CGVector(transitionVector.dx / transitionVectorLength, transitionVector.dy / new nfloat(transitionVectorLength));

            for (int y = 0; y < verticalSlices; y++)
            {
                for (int x = 0; x < horizontalSileces; x++)
                {
                    var fromContentLayer = new CALayer {
                        Frame = new CGRect(x + sliceSize * -1f, y * sliceSize * -1f, containerView.Bounds.Width, containerView.Bounds.Height),
                        RasterizationScale = fromViewSnapshot.CurrentScale,
                        Contents           = fromViewSnapshot.CGImage
                    };

                    var toContentLayer = new CALayer();
                    toContentLayer.Frame = new CGRect(x * sliceSize * -1f, y * sliceSize * -1f, containerView.Bounds.Width, containerView.Bounds.Height);

                    CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() => {
                        bool wereActionDisabled      = CATransaction.DisableActions;
                        CATransaction.DisableActions = true;

                        toContentLayer.RasterizationScale = toViewSnapshot.CurrentScale;
                        toContentLayer.Contents           = toViewSnapshot.CGImage;

                        CATransaction.DisableActions = wereActionDisabled;
                    });

                    var toCheckboardSquareView = new UIView {
                        Frame  = new CGRect(x * sliceSize, y * sliceSize, sliceSize, sliceSize),
                        Opaque = false
                    };

                    toCheckboardSquareView.Layer.MasksToBounds = true;
                    toCheckboardSquareView.Layer.DoubleSided   = false;
                    toCheckboardSquareView.Layer.Transform     = CATransform3D.MakeRotation(NMath.PI, 0f, 1f, 0f);
                    toCheckboardSquareView.Layer.AddSublayer(toContentLayer);

                    var fromCheckboardSquareView = new UIView {
                        Frame  = new CGRect(x * sliceSize, y * sliceSize, sliceSize, sliceSize),
                        Opaque = false
                    };

                    fromCheckboardSquareView.Layer.MasksToBounds = true;
                    fromCheckboardSquareView.Layer.DoubleSided   = false;
                    fromCheckboardSquareView.Layer.Transform     = CATransform3D.Identity;
                    fromCheckboardSquareView.Layer.AddSublayer(fromContentLayer);

                    transitionContainer.AddSubview(toCheckboardSquareView);
                    transitionContainer.AddSubview(fromCheckboardSquareView);
                }
            }

            int sliceAnimationsPending = 0;

            for (int y = 0; y < verticalSlices; y++)
            {
                for (int x = 0; x < horizontalSileces; x++)
                {
                    double toIndex = y * horizontalSileces * 2f + (x * 2);
                    UIView toCheckboardSquareView = transitionContainer.Subviews[(int)toIndex];

                    double fromIndex = y * horizontalSileces * 2f + (x * 2 + 1);
                    UIView fromCheckboardSquareView = transitionContainer.Subviews[(int)fromIndex];

                    CGVector sliceOriginVector;

                    if (isPush)
                    {
                        sliceOriginVector = new CGVector(fromCheckboardSquareView.Frame.GetMinX() - transitionContainer.Bounds.GetMinX(), fromCheckboardSquareView.Frame.GetMinY() - transitionContainer.Bounds.GetMinY());
                    }
                    else
                    {
                        sliceOriginVector = new CGVector(fromCheckboardSquareView.Frame.GetMaxX() - transitionContainer.Bounds.GetMaxX(), fromCheckboardSquareView.Frame.GetMaxY() - transitionContainer.Bounds.GetMaxY());
                    }

                    // Project sliceOriginVector onto transitionVector.
                    nfloat dot        = sliceOriginVector.dx * transitionVector.dx + sliceOriginVector.dy * transitionVector.dy;
                    var    projection = new CGVector(transitionUnitVector.dx * dot / transitionVectorLength, transitionUnitVector.dy * dot / transitionVectorLength);

                    // Compute the length of the projection.
                    var projectionLength = NMath.Sqrt(projection.dx * projection.dx + projection.dy * projection.dy);

                    double startTime = projectionLength / (transitionVectorLength + transitionSpacing) * transitionDuration;
                    double duration  = ((projectionLength + transitionSpacing) / (transitionVectorLength + transitionSpacing) * transitionDuration) - startTime;

                    sliceAnimationsPending++;

                    UIView.Animate(duration, startTime, UIViewAnimationOptions.TransitionNone, () => {
                        toCheckboardSquareView.Layer.Transform   = CATransform3D.Identity;
                        fromCheckboardSquareView.Layer.Transform = CATransform3D.MakeRotation(NMath.PI, 0f, 1f, 0f);
                    }, () => {
                        if (--sliceAnimationsPending == 0)
                        {
                            bool wasCancelled = transitionContext.TransitionWasCancelled;
                            transitionContainer.RemoveFromSuperview();
                            transitionContext.CompleteTransition(!wasCancelled);
                        }
                    }
                                   );
                }
            }
        }
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var toViewController   = GetViewController(transitionContext, UITransitionContext.ToViewControllerKey);
            var fromViewController = GetViewController(transitionContext, UITransitionContext.FromViewControllerKey);

            UIView fromView = fromViewController.View;
            UIView toView   = toViewController.View;

            // Add the toView to the container
            UIView containerView = transitionContext.ContainerView;

            toView.Frame = transitionContext.GetFinalFrameForViewController(toViewController);
            var toFrame = fromView.Frame;

            toFrame.Offset(fromView.Frame.Size.Width, 0);
            toView.Frame = toFrame;
            containerView.AddSubview(toView);

            // Add a perspective transform
            var transform = CATransform3D.Identity;

            transform.m34 = -0.005f;
            containerView.Layer.SublayerTransform = transform;

            CGSize size = toView.Frame.Size;

            float foldWidth = (float)(size.Width * 0.5f / Folds);

            // arrays that hold the snapshot views
            var fromViewFolds = new List <UIView>();
            var toViewFolds   = new List <UIView>();

            for (int i = 0; i < Folds; i++)
            {
                float offset = i * foldWidth * 2;

                // the left and right side of the fold for the from- view, with identity transform and 0.0 alpha
                // on the shadow, with each view at its initial position
                UIView leftFromViewFold = CreateSnapshot(fromView, false, offset, true);
                leftFromViewFold.Layer.Position = new CGPoint(offset, size.Height / 2f);
                fromViewFolds.Add(leftFromViewFold);
                leftFromViewFold.Subviews[1].Alpha = 0f;

                UIView rightFromViewFold = CreateSnapshot(fromView, false, offset + foldWidth, false);
                rightFromViewFold.Layer.Position = new CGPoint(offset + foldWidth * 2f, size.Height / 2f);
                fromViewFolds.Add(rightFromViewFold);
                rightFromViewFold.Subviews[1].Alpha = 0f;

                // the left and right side of the fold for the to- view, with a 90-degree transform and 1.0 alpha
                // on the shadow, with each view positioned at the very edge of the screen
                UIView leftToViewFold = CreateSnapshot(toView, true, offset, true);
                leftToViewFold.Layer.Position  = new CGPoint(Reverse ? size.Width : 0f, size.Height / 2f);
                leftToViewFold.Layer.Transform = CATransform3D.MakeRotation((float)Math.PI / 2f, 0f, 1f, 0f);
                toViewFolds.Add(leftToViewFold);

                UIView rightToViewFold = CreateSnapshot(toView, true, offset + foldWidth, false);
                rightToViewFold.Layer.Position  = new CGPoint(Reverse ? size.Width : 0f, size.Height / 2f);
                rightToViewFold.Layer.Transform = CATransform3D.MakeRotation(-(float)Math.PI / 2f, 0f, 1f, 0f);
                toViewFolds.Add(rightToViewFold);
            }

            //move the from- view off screen
            var fromFrame = fromView.Frame;

            fromFrame.Offset(fromView.Frame.Size.Width, 0);
            fromView.Frame = fromFrame;

            // create the animation
            double duration = TransitionDuration(transitionContext);

            Action animation = () => {
                for (int i = 0; i < Folds; i++)
                {
                    float offset = i * foldWidth * 2;

                    // the left and right side of the fold for the from- view, with 90 degree transform and 1.0 alpha
                    // on the shadow, with each view positioned at the edge of thw screen.
                    UIView leftFromView = fromViewFolds[i * 2];
                    leftFromView.Layer.Position    = new CGPoint(Reverse ? 0f : size.Width, size.Height / 2f);
                    leftFromView.Layer.Transform   = transform.Rotate((float)Math.PI / 2f, 0f, 1f, 0f);
                    leftFromView.Subviews[1].Alpha = 1f;

                    UIView rightFromView = fromViewFolds[i * 2 + 1];
                    rightFromView.Layer.Position    = new CGPoint(Reverse ? 0f : size.Width, size.Height / 2f);
                    rightFromView.Layer.Transform   = transform.Rotate(-(float)Math.PI / 2f, 0f, 1f, 0f);
                    rightFromView.Subviews[1].Alpha = 1f;

                    // the left and right side of the fold for the to- view, with identity transform and 0.0 alpha
                    // on the shadow, with each view at its final position
                    UIView leftToView = toViewFolds[i * 2];
                    leftToView.Layer.Position    = new CGPoint(offset, size.Height / 2f);
                    leftToView.Layer.Transform   = CATransform3D.Identity;
                    leftToView.Subviews[1].Alpha = 0f;

                    UIView rightToView = toViewFolds[i * 2 + 1];
                    rightToView.Layer.Position    = new CGPoint(offset + foldWidth * 2f, size.Height / 2f);
                    rightToView.Layer.Transform   = CATransform3D.Identity;
                    rightToView.Subviews[1].Alpha = 0f;
                }
            };

            UIView.Animate(duration, animation, () => {
                // remove the snapshot views
                foreach (UIView view in toViewFolds)
                {
                    view.RemoveFromSuperview();
                }

                foreach (UIView view in fromViewFolds)
                {
                    view.RemoveFromSuperview();
                }

                // restore the to- and from- to the initial location
                toView.Frame   = containerView.Bounds;
                fromView.Frame = containerView.Bounds;
                transitionContext.CompleteTransition(!transitionContext.TransitionWasCancelled);
            });
        }
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var fromViewController = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
            var toViewController   = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);

            UIView containerView = transitionContext.ContainerView;
            var    fromView      = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
            var    toView        = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            bool isPresenting = (toViewController.PresentingViewController == fromViewController);

            var fromFrame = transitionContext.GetInitialFrameForViewController(fromViewController);
            var toFrame   = transitionContext.GetFinalFrameForViewController(toViewController);

            var offset = new CGVector(0f, 0f);

            switch (targetEdge)
            {
            case UIRectEdge.Top:
                offset = new CGVector(0f, 1f);
                break;

            case UIRectEdge.Bottom:
                offset = new CGVector(0f, -1f);
                break;

            case UIRectEdge.Left:
                offset = new CGVector(1f, 0f);
                break;

            case UIRectEdge.Right:
                offset = new CGVector(-1, 0);
                break;

            default:
                offset = new CGVector(0f, 0f);
                // TODO: error
                break;
            }

            if (isPresenting)
            {
                fromView.Frame = fromFrame;
                toView.Frame   = new CGRect(toFrame.X + (toFrame.Size.Width * offset.dx * -1), toFrame.Y + (toFrame.Size.Height * offset.dy * -1), toFrame.Size.Width, toFrame.Size.Height);
            }
            else
            {
                fromView.Frame = fromFrame;
                toView.Frame   = toFrame;
            }

            if (isPresenting)
            {
                containerView.AddSubview(toView);
            }
            else
            {
                containerView.InsertSubviewBelow(toView, fromView);
            }

            var duration = TransitionDuration(transitionContext);

            UIView.Animate(duration, 0, UIViewAnimationOptions.TransitionNone, () => {
                toView.Frame = isPresenting ?
                               toFrame : new CGRect(fromFrame.X + (fromFrame.Size.Width * offset.dx), fromFrame.Y + (fromFrame.Size.Height * offset.dy), fromFrame.Size.Width, fromFrame.Size.Height);
            }, () => {
                bool wasCancel = transitionContext.TransitionWasCancelled;

                if (wasCancel)
                {
                    toView.RemoveFromSuperview();
                    transitionContext.CompleteTransition(!wasCancel);
                }
            });
        }