コード例 #1
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);

            fromView.Alpha = 1f;
            toView.Alpha   = 0f;

            containerView.AddSubview(toView);
            var transitionDuration = TransitionDuration(transitionContext);

            UIView.Animate(transitionDuration, 0, UIViewAnimationOptions.TransitionNone, () => {
                fromView.Alpha = 0f;
                toView.Alpha   = 1f;
            }, () => {
                bool wasCancel = transitionContext.TransitionWasCancelled;
                transitionContext.CompleteTransition(!wasCancel);
            }
                           );
        }
コード例 #2
0
        void PerformFadeAnimation(IUIViewControllerContextTransitioning transitionContext)
        {
            var fromView = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
            var toView   = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            var viewToFade     = toView;
            var beginningAlpha = 0.0f;
            var endingAlpha    = 1.0f;

            if (IsDismissing)
            {
                viewToFade     = fromView;
                beginningAlpha = 1.0f;
                endingAlpha    = 0.0f;
            }

            viewToFade.Alpha = beginningAlpha;

            UIView.Animate(FadeDuration(transitionContext), () => { viewToFade.Alpha = endingAlpha; },
                           () => {
                if (!ShouldPerformZoomingAnimation)
                {
                    CompleteTransition(transitionContext);
                }
            });
        }
コード例 #3
0
        public void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            UIView containerView = transitionContext.ContainerView;
            UIView toView        = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            if (transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey) == DestinationViewController)
            {
                // Presenting.
                UIView.PerformWithoutAnimation(() => {
                    toView.Alpha = 0;
                    containerView.AddSubview(toView);
                });

                double transitionContextDuration = TransitionDuration(transitionContext);

                UIView.AnimateNotify(transitionContextDuration, () => {
                    toView.Alpha = 1;
                }, transitionContext.CompleteTransition);
            }
            else
            {
                // Dismissing.
                var fromView = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
                UIView.PerformWithoutAnimation(() => containerView.InsertSubviewBelow(toView, fromView));

                var transitionContextDuration = TransitionDuration(transitionContext);

                UIView.AnimateNotify(transitionContextDuration, () => {
                    fromView.Alpha = 0;
                }, transitionContext.CompleteTransition);
            }
        }
コード例 #4
0
		public void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)
		{
			UIView containerView = transitionContext.ContainerView;
			UIView toView = transitionContext.GetViewFor (UITransitionContext.ToViewKey);

			if (transitionContext.GetViewControllerForKey (UITransitionContext.ToViewControllerKey) == DestinationViewController) {
				// Presenting.
				UIView.PerformWithoutAnimation (() => {
					toView.Alpha = 0;
					containerView.AddSubview (toView);
				});

				double transitionContextDuration = TransitionDuration (transitionContext);

				UIView.AnimateNotify (transitionContextDuration, () => {
					toView.Alpha = 1;
				}, transitionContext.CompleteTransition);
			} else {
				// Dismissing.
				var fromView = transitionContext.GetViewFor (UITransitionContext.FromViewKey);
				UIView.PerformWithoutAnimation (() => containerView.InsertSubviewBelow (toView, fromView));

				var transitionContextDuration = TransitionDuration (transitionContext);

				UIView.AnimateNotify (transitionContextDuration, () => {
					fromView.Alpha = 0;
				}, transitionContext.CompleteTransition);
			}
		}
コード例 #5
0
        public void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var fromViewController = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
            var toViewController   = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);

            UIView containerView = transitionContext.ContainerView;

            var  toView       = transitionContext.GetViewFor(UITransitionContext.ToViewKey);
            var  fromView     = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
            bool isPresenting = (fromViewController == PresentingViewController);

            var fromViewFinalFrame = transitionContext.GetFinalFrameForViewController(fromViewController);
            var toViewInitialFrame = transitionContext.GetInitialFrameForViewController(toViewController);

            var toViewFinalFrame = transitionContext.GetFinalFrameForViewController(toViewController);

            if (toView != null)
            {
                containerView.AddSubview(toView);
            }

            if (isPresenting)
            {
                toViewInitialFrame.X    = containerView.Bounds.GetMinX();
                toViewInitialFrame.Y    = containerView.Bounds.GetMaxY();
                toViewInitialFrame.Size = toViewFinalFrame.Size;

                toView.Frame = toViewInitialFrame;
            }
            else
            {
                fromView.Frame.Offset(0f, fromView.Frame.Height);
                fromViewFinalFrame = new CGRect(fromView.Frame.X, fromView.Frame.Y + fromView.Frame.Height, fromViewFinalFrame.Width, fromViewFinalFrame.Height);
            }

            double transitionDuration = TransitionDuration(transitionContext);

            UIView.Animate(transitionDuration, 0, UIViewAnimationOptions.TransitionNone, () => {
                if (isPresenting)
                {
                    toView.Frame = toViewFinalFrame;
                }
                else
                {
                    fromView.Frame = fromViewFinalFrame;
                }
            }, () => {
                bool wasCancelled = transitionContext.TransitionWasCancelled;
                transitionContext.CompleteTransition(!wasCancelled);
            }
                           );
        }
コード例 #6
0
        public void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var    fromViewController = transitionContext.GetViewControllerForKey(UITransitionContext.FromViewControllerKey);
            var    toViewController   = transitionContext.GetViewControllerForKey(UITransitionContext.ToViewControllerKey);
            UIView containerView      = transitionContext.ContainerView;

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

            bool isPresenting = (fromViewController == PresentingViewController);

            if (toView != null)
            {
                containerView.AddSubview(toView);
            }

            if (isPresenting)
            {
                toView.Alpha = 0f;

                if (fromView != null)
                {
                    fromView.Frame = transitionContext.GetFinalFrameForViewController(fromViewController);
                }

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

            double transitionDuration = TransitionDuration(transitionContext);

            UIView.Animate(transitionDuration, 0, UIViewAnimationOptions.TransitionNone, () => {
                if (toView != null)
                {
                    toView.Alpha = isPresenting ? 1f : 0f;
                }
            }, () => {
                bool wasCancelled = transitionContext.TransitionWasCancelled;
                transitionContext.CompleteTransition(!wasCancelled);

                if (isPresenting == false)
                {
                    fromView.Alpha = 1f;
                }
            }
                           );
        }
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var containerView = transitionContext.ContainerView;
            var fromView      = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
            var toView        = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            var detailView = IsPresenting ? toView : fromView;

            detailView.Frame = new CGRect(0, 0, fromView.Bounds.Width, fromView.Bounds.Height);

            var initialFrame = IsPresenting ? StartingFrame : detailView.Frame;
            var finalFrame   = IsPresenting ? detailView.Frame : StartingFrame;

            var xScaleFactor = IsPresenting ? initialFrame.Width / finalFrame.Width : finalFrame.Width / initialFrame.Width;
            var yScaleFactor = IsPresenting ? initialFrame.Height / finalFrame.Height : finalFrame.Height / initialFrame.Height;

            var scaleTransform = CGAffineTransform.MakeScale(xScaleFactor, yScaleFactor);

            if (IsPresenting)
            {
                detailView.Transform     = scaleTransform;
                detailView.Center        = new CGPoint(initialFrame.GetMidX(), initialFrame.GetMidY());
                detailView.ClipsToBounds = true;
            }

            containerView.AddSubview(toView);
            containerView.BringSubviewToFront(detailView);

            UIView.Animate(Duration, 0, UIViewAnimationOptions.CurveEaseInOut,
                           () =>
            {
                detailView.Transform = IsPresenting ? CGAffineTransform.MakeIdentity() : scaleTransform;
                detailView.Center    = new CGPoint(finalFrame.GetMidX(), finalFrame.GetMidY());

                if (!IsPresenting)
                {
                    fromView.Alpha = 0f;
                }
            },
                           () =>
            {
                if (!IsPresenting)
                {
                    fromView.RemoveFromSuperview();
                }
                transitionContext.CompleteTransition(true);
            }
                           );
        }
コード例 #8
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);

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

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

            if (targetEdge == UIRectEdge.Left)
            {
                offset = new CGVector(-1f, 0f);
            }
            else if (targetEdge == UIRectEdge.Right)
            {
                offset = new CGVector(1f, 0f);
            }

            fromView.Frame = fromFrame;

            CGRect auxFrame = toFrame;

            auxFrame.Offset(toFrame.Width * offset.dx * -1f, toFrame.Height * offset.dy * -1f);
            toView.Frame = auxFrame;

            containerView.AddSubview(toView);

            var duration = TransitionDuration(transitionContext);

            UIView.Animate(duration, 0, UIViewAnimationOptions.TransitionNone, () => {
                var fromFrameAux = fromFrame;
                fromFrameAux.Offset(fromFrame.Width * offset.dx, fromFrame.Height * offset.dy);
                fromView.Frame = fromFrameAux;

                toView.Frame = toFrame;
            }, () => {
                transitionContext.CompleteTransition(!transitionContext.TransitionWasCancelled);
            }
                           );
        }
コード例 #9
0
        public void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var fromView = transitionContext.GetViewFor(UITransitionContext.FromViewKey);
            var toView   = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            toView.Alpha = 0;

            transitionContext.ContainerView.AddSubview(fromView);
            transitionContext.ContainerView.AddSubview(toView);

            UIView.Animate(TransitionDuration(transitionContext), () =>
            {
                toView.Alpha   = 1;
                fromView.Alpha = 0;
            }, () =>
            {
                transitionContext.CompleteTransition(true);
            });
        }
        nfloat BackgroundAlphaForPanning(nfloat verticalDelta)
        {
            var startingAlpha       = 1.0f;
            var finalAlpha          = 0.1f;
            var totalAvailableAlpha = startingAlpha - finalAlpha;

            var maximumDelta = (_transitionContext == null) ? 0.0f : _transitionContext.GetViewFor(UITransitionContext.FromViewKey).Bounds.Height / 2.0f;

            var deltaAsPercentageOfMaximum = (nfloat)Math.Min(Math.Abs(verticalDelta) / maximumDelta, 1.0);

            return(startingAlpha - (deltaAsPercentageOfMaximum * totalAvailableAlpha));
        }
        public void DidPan(UIPanGestureRecognizer panGestureRecognizer, UIView viewToPan, CGPoint anchorPoint)
        {
            var fromView = _transitionContext?.GetViewFor(UITransitionContext.FromViewKey);
            var translatedPanGesturePoint = panGestureRecognizer.TranslationInView(fromView);
            var newCenterPoint            = new CGPoint(anchorPoint.X, anchorPoint.Y + translatedPanGesturePoint.Y);

            viewToPan.Center = newCenterPoint;

            var verticalDelta = newCenterPoint.Y - anchorPoint.Y;

            var backgroundAlpha = BackgroundAlphaForPanning(verticalDelta);

            if (fromView != null)
            {
                fromView.BackgroundColor = fromView.BackgroundColor.ColorWithAlpha(backgroundAlpha);
            }

            if (panGestureRecognizer.State == UIGestureRecognizerState.Ended)
            {
                FinishPan(panGestureRecognizer, verticalDelta, viewToPan, anchorPoint);
            }
        }
コード例 #12
0
        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);
            }
        }
コード例 #13
0
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var containerView = transitionContext.ContainerView;
            var toView        = transitionContext.GetViewFor(UITransitionContext.ToViewKey);

            containerView.AddSubview(toView);
            toView.Alpha = 0;
            UIView.Animate(_duration, () =>
            {
                toView.Alpha = 1;
            }, () =>
            {
                transitionContext.CompleteTransition(true);
            });
        }
コード例 #14
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);

            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);
                }
            });
        }
コード例 #15
0
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var presenting = Operation == UINavigationControllerOperation.Push;

            // Determine which is the master view and which is the detail view that we're navigating to and from. The container view will house the views for transition animation.
            var containerView = transitionContext.ContainerView;
            var toView        = transitionContext.GetViewFor(UITransitionContext.ToViewKey);
            var fromView      = transitionContext.GetViewFor(UITransitionContext.FromViewKey);

            var storyFeedView   = presenting ? fromView : toView;
            var storyDetailView = presenting ? toView : fromView;

            // Determine the starting frame of the detail view for the animation. When we're presenting, the detail view will grow out of the thumbnail frame. When we're dismissing, the detail view will shrink back into that same thumbnail frame.
            var initialFrame = presenting ? ThumbnailFrame : storyDetailView.Frame;
            var finalFrame   = presenting ? storyDetailView.Frame : ThumbnailFrame;

            // Resize the detail view to fit within the thumbnail's frame at the beginning of the push animation and at the end of the pop animation while maintaining it's inherent aspect ratio.
            var initialFrameAspectRatio = initialFrame.Width / initialFrame.Height;
            var storyDetailAspectRatio  = storyDetailView.Frame.Width / storyDetailView.Frame.Height;

            if (initialFrameAspectRatio > storyDetailAspectRatio)
            {
                initialFrame.Size = new CGSize(initialFrame.Height * storyDetailAspectRatio, initialFrame.Height);
            }
            else
            {
                initialFrame.Size = new CGSize(initialFrame.Width, initialFrame.Width / storyDetailAspectRatio);
            }

            var finalFrameAspectRatio = finalFrame.Width / finalFrame.Height;
            var resizedFinalFrame     = finalFrame;

            if (finalFrameAspectRatio > storyDetailAspectRatio)
            {
                resizedFinalFrame.Size = new CGSize(finalFrame.Height * storyDetailAspectRatio, finalFrame.Height);
            }
            else
            {
                resizedFinalFrame.Size = new CGSize(finalFrame.Width, finalFrame.Width / storyDetailAspectRatio);
            }

            // Determine how much the detail view needs to grow or shrink.
            var scaleFactor       = resizedFinalFrame.Width / initialFrame.Width;
            var growScaleFactor   = presenting ? scaleFactor : 1 / scaleFactor;
            var shrinkScaleFactor = 1 / growScaleFactor;

            if (presenting)
            {
                // Shrink the detail view for the initial frame. The detail view will be scaled to CGAffineTransformIdentity below.
                storyDetailView.Transform     = CGAffineTransform.MakeScale(shrinkScaleFactor, shrinkScaleFactor);
                storyDetailView.Center        = new CGPoint(ThumbnailFrame.GetMidX(), ThumbnailFrame.GetMidY());
                storyDetailView.ClipsToBounds = true;
            }

            // Set the initial state of the alpha for the master and detail views so that we can fade them in and out during the animation.
            storyDetailView.Alpha = presenting ? 0 : 1;
            storyFeedView.Alpha   = presenting ? 1 : 0;

            // Add the view that we're transitioning to to the container view that houses the animation.
            containerView.AddSubview(toView);
            containerView.BringSubviewToFront(storyDetailView);

            // Animate the transition.
            UIView.Animate(_duration, 0, UIViewAnimationOptions.CurveEaseInOut, () =>
            {
                // Fade the master and detail views in and out.
                storyDetailView.Alpha = presenting ? 1 : 0;
                storyFeedView.Alpha   = presenting ? 0 : 1;

                if (presenting)
                {
                    // Scale the master view in parallel with the detail view (which will grow to its inherent size). The translation gives the appearance that the anchor point for the zoom is the center of the thumbnail frame.
                    var scale     = CGAffineTransform.MakeScale(growScaleFactor, growScaleFactor);
                    var translate = CGAffineTransform.Translate(storyFeedView.Transform, storyFeedView.Frame.GetMidX() - this.ThumbnailFrame.GetMidX(), storyFeedView.Frame.GetMidY() - this.ThumbnailFrame.GetMidY());

                    storyFeedView.Transform   = translate * scale;
                    storyDetailView.Transform = CGAffineTransform.MakeIdentity();
                }
                else
                {
                    // Return the master view to its inherent size and position and shrink the detail view.
                    storyFeedView.Transform   = CGAffineTransform.MakeIdentity();
                    storyDetailView.Transform = CGAffineTransform.MakeScale(shrinkScaleFactor, shrinkScaleFactor);
                }

                // Move the detail view to the final frame position.
                storyDetailView.Center = new CGPoint(finalFrame.GetMidX(), finalFrame.GetMidY());
            }, () =>
            {
                transitionContext.CompleteTransition(true);
            });
        }
コード例 #16
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);
                        }
                    }
                                   );
                }
            }
        }
コード例 #17
0
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            const float Inset = 20;

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

            var smallFrame = sourceView.ConvertRectToView(sourceView.Bounds, container);
            var bigFrame   = toView.Frame.Inset(-Inset, -Inset);

            var coverView = new UIView(bigFrame);

            Theme.Default.StyleRoundBorder(coverView);
            coverView.BackgroundColor = UIColor.White;

            /// <summary>
            /// Snapshot is used to give effect of smoothly appearing view, with alpha and frame size.
            /// </summary>
            UIView SetSnapshot(UIView view)
            {
                var snapshot = view.SnapshotView(false) ?? view.SnapshotView(true);

                coverView.Add(snapshot);
                snapshot.Frame            = coverView.Bounds.Inset(Inset, Inset);
                snapshot.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
                return(snapshot);
            }

            void Animate(CGRect frame1, CGRect frame2, float alpha1, float alpha2, UIView innerView)
            {
                container.AddSubview(coverView);
                var snapshot = SetSnapshot(innerView);

                coverView.Frame = frame1;
                snapshot.Alpha  = alpha1;

                UIView.Animate(TransitionDuration(transitionContext), () =>
                {
                    coverView.Frame = frame2;
                    snapshot.Alpha  = alpha2;
                }, () =>
                {
                    var finished = !transitionContext.TransitionWasCancelled;

                    if (!finished)
                    {
                        toView.RemoveFromSuperview();
                    }
                    else
                    {
                        container.BringSubviewToFront(toView);
                    }

                    coverView.RemoveFromSuperview();
                    transitionContext.CompleteTransition(finished);
                });
            }

            if (operation == UINavigationControllerOperation.Push)
            {
                container.InsertSubview(toView, 0);
                Animate(smallFrame, bigFrame, 0, 1, toView);
            }
            else
            {
                container.AddSubview(toView);
                Animate(bigFrame, smallFrame, 1, 0, fromView);
            }
        }
        public override void AnimateTransition(IUIViewControllerContextTransitioning transitionContext)
        {
            var containerView = transitionContext.ContainerView;

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

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

            var detailView = IsPresenting ? toView : fromView;

            detailView.Frame = new CGRect(0, 0, fromView.Bounds.Width, fromView.Bounds.Height);

            var artwork      = detailView.ViewWithTag(CustomAnimatorTag) as UIImageView;
            var artworkFrame = artwork.Frame;

            artwork.Image = SelectedImage;
            artwork.Alpha = 0;

            var transitionImageView = new UIImageView(IsPresenting ? StartingFrame : artworkFrame);

            transitionImageView.Image = SelectedImage;

            containerView.AddSubview(transitionImageView);

            toView.Frame = new CGRect(0, 0, fromView.Bounds.Width, fromView.Bounds.Height);
            toView.Alpha = IsPresenting ? 0 : 1;

            var initialFrame = IsPresenting ? StartingFrame : detailView.Frame;
            var finalFrame   = IsPresenting ? detailView.Frame : StartingFrame;

            var xScaleFactor = IsPresenting ? initialFrame.Width / finalFrame.Width : finalFrame.Width / initialFrame.Width;
            var yScaleFactor = IsPresenting ? initialFrame.Height / finalFrame.Height : finalFrame.Height / initialFrame.Height;

            var scaleTransform = CGAffineTransform.MakeScale(xScaleFactor, yScaleFactor);

            if (IsPresenting)
            {
                detailView.Transform     = scaleTransform;
                detailView.Center        = new CGPoint(initialFrame.GetMidX(), initialFrame.GetMidY());
                detailView.ClipsToBounds = true;
            }

            toView.LayoutIfNeeded();

            UIView.Animate(Duration, 0, UIViewAnimationOptions.CurveEaseInOut, () =>
            {
                detailView.Transform = IsPresenting ? CGAffineTransform.MakeIdentity() : scaleTransform;
                detailView.Center    = new CGPoint(finalFrame.GetMidX(), finalFrame.GetMidY());

                transitionImageView.Frame = IsPresenting ? artworkFrame : StartingFrame;

                detailView.Alpha = IsPresenting ? 1 : 0;
            },
                           () => {
                transitionContext.CompleteTransition(true);
                transitionImageView.RemoveFromSuperview();
                artwork.Alpha = 1;
            });
        }