{"id":19177,"date":"2015-06-11T17:03:42","date_gmt":"2015-06-11T21:03:42","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=19177"},"modified":"2015-06-11T17:03:42","modified_gmt":"2015-06-11T21:03:42","slug":"crafting-5-star-ios-experiences-with-transitions","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/crafting-5-star-ios-experiences-with-transitions\/","title":{"rendered":"Crafting 5 Star iOS Experiences with Transitions"},"content":{"rendered":"<p>\t\t\t\tLast month, I wrote a blog post\u00a0on <a href=\"\/crafting-5-star-ios-experiences-with-animations\/\" target=\"_blank\">creating beautiful animations using iOS APIs<\/a>. Subtle use of animations and transitions in iOS can turn an average\u00a0app into a five-star app. iOS has many built-in transitions between views that can be leveraged as a great starting point for adding animations to your iOS apps. However, with just a little bit of work, you can create custom transitions that will give your app a unique experience, spice up an otherwise generic user experience, and take your iOS app to the next level.<\/p>\n<p><a href=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/transition.gif\"><img decoding=\"async\" class=\"aligncenter  wp-image-19220\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/transition.gif\" alt=\"transition\" width=\"282\" height=\"503\" \/><\/a><\/p>\n<h3>Getting Started<\/h3>\n<p>Normally, when we call the following API,\u00a0we would expect our view to animate in from the left side:<\/p>\n<pre class=\"lang:csharp decode:true\">\u00a0PresentViewControllerAsync(ourViewController, true);\u00a0<\/pre>\n<p>If we want to spice up our app with a custom transition, we can continue to use the same API to present the new UIViewController, but we&#8217;ll need a\u00a0way to tell iOS about our custom transition.\u00a0iOS gives us an easy way to customize a UIViewController&#8217;s transition via the delegate pattern: just set the\u00a0view controller&#8217;s transition delegate to a subclass of UIViewControllerTransitionDelegate.<\/p>\n<p>Every time you ask iOS to present a new view controller, UIKit will check to see if it has a transition delegate to use in place of the default transitions. If you don&#8217;t provide a transition delegate, it will use the built in transitions (i.e. animating the new view in from the left, or, if a modal transition, from the bottom).<\/p>\n<h3>Creating a Custom\u00a0Transition<\/h3>\n<p>Transitions are made up of three subclasses: <a href=\"http:\/\/docs.go-mono.com\/index.aspx?link=T:UIKit.UIViewControllerAnimatedTransitioning\">UIViewControllerAnimatedTransitioning<\/a>, <a href=\"http:\/\/docs.go-mono.com\/index.aspx?link=T%3aUIKit.UIViewControllerTransitioningDelegate\">UIViewControllerTransitionDelegate<\/a>,\u00a0and\u00a0<a href=\"http:\/\/docs.go-mono.com\/index.aspx?link=T%3aUIKit.UIPresentationController\">UIPresentationController<\/a>. I suggest starting with a subclass of UIViewControllerAnimatedTransitioning and then moving on to the transition delegate, as the AnimatedTransitioning class is where we&#8217;ll implement our custom transition.<\/p>\n<h3>Implementing UIViewControllerAnimatedTransitioning<\/h3>\n<p>To implement UIViewControllerAnimatedTransitioning, you must use two main methods. The TransitionDuration method defines exactly how long the transition should last, while the AnimationTransition method is where all the magic of actually making a UIViewController animate happens.\u00a0Below is\u00a0a sample implementation that I&#8217;ve taken from the iOS version of my\u00a0Dutch Spelling app:<\/p>\n<pre class=\"lang:csharp decode:true\">\npublic class MyCustomAnimator : UIViewControllerAnimatedTransitioning\n{\n    public bool IsPresentation = true;\n    CGRect startFrame = CGRect.Empty;\n\n    public MyCustomAnimator(CoreGraphics.CGRect frame)\n    {\n       startFrame = frame;\n    }\n\n    public override double TransitionDuration (IUIViewControllerContextTransitioning transitionContext)\n    {\n       \/\/How long will the transition last?\n       return 0.8;\n    }\n\n    public override void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)\n    {\n       \/\/Where we'll add our transition!\n    }\n}\n<\/pre>\n<p>The key part of UIViewControllerAnimatedTransitioning is the AnimateTransition method. This method allows you access to both the current view controller and the new view controller you want presented to the user. You can animate the view controllers view using the wonderful iOS animation APIs, which allow you to scale, fade, rotate, and create beautiful transitions. You can see how I have implemented the AnimateTransition method to show a basic transition:<\/p>\n<pre class=\"lang:csharp decode:true\">\npublic override void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)\n{\n    \/\/The current view controller\n    var fromVC = transitionContext.GetViewControllerForKey (UITransitionContext.FromViewControllerKey);\n    var fromView = fromVC.View;\n\n    \/\/The view controller we wish to present to the user\n    var toVC = transitionContext.GetViewControllerForKey (UITransitionContext.ToViewControllerKey);\n    var toView = toVC.View;\n\n    \/\/ContainerView is where our animation will live\n    var containerView = transitionContext.ContainerView;\n\n    var isPresentation = IsPresentation;\n    if (isPresentation)\n    {\n        containerView.AddSubview(toView);\n    }\n\n    var animatingVC = isPresentation ? toVC : fromVC;\n    var animatingView = animatingVC.View;\n\n    var appearedFrame = transitionContext.GetFinalFrameForViewController (animatingVC);\n    var dismissedFrame = this.startFrame;\n\n    var initialFrame = new CGRect(0, toView.Frame.Height + 100, toView.Frame.Width, toView.Frame.Height);\n    var finalFrame = isPresentation ? appearedFrame : dismissedFrame;\n    animatingView.Frame = initialFrame;\n\n    var lessonOptionsVC = toVC as LessonTypeViewController;\n    var defaultFrame = lessonOptionsVC.ContainerView.Frame;\n    lessonOptionsVC.ContainerView.Frame = new CGRect(lessonOptionsVC.ContainerView.Frame.X, -500, lessonOptionsVC.ContainerView.Frame.Width, lessonOptionsVC.ContainerView.Frame.Height);\n\n    UIView.AnimateNotify (0.5f,\n                0,\n                300.0f,\n                5.0f,\n                UIViewAnimationOptions.AllowUserInteraction | UIViewAnimationOptions.BeginFromCurrentState,\n                () =&gt; {\n                animatingView.Frame = finalFrame;\n                lessonOptionsVC.ContainerView.Frame = defaultFrame;\n\n            },  new UICompletionHandler((bool finished) =&amp;gt; {\n                if(!isPresentation){\n                    fromView.RemoveFromSuperview();\n                }\n                transitionContext.CompleteTransition(true);\n     }));\n}\n<\/pre>\n<h3>Implementing\u00a0UIViewControllerTransitionDelegate<\/h3>\n<p>The main purpose of the UIViewControllerTransitionDelegate class\u00a0is to manage the animator object that performs the animations. It will need to reference a subclass of UIViewControllerAnimatedTransitioning, which contains a few key properties that must be overloaded:<\/p>\n<pre class=\"lang:csharp decode:true\">\npublic class MyCustomOptionsTransitionDelegate : UIViewControllerTransitioningDelegate\n{\n    CoreGraphics.CGRect startFrame;\n    private MyCustomOptionsTransitionDelegate lessonOptionsPresentationController;\n\n    private LessonOptionsAnimator animationTransitioning;\n    public LessonOptionsAnimator AnimationTransitioning \n    {\n       get\n       {\n          if (animationTransitioning == null) {\n             animationTransitioning = new LessonOptionsAnimator(startFrame);\n          }\n          return animationTransitioning;\n       }\n    }\n\n    public LessonOptionsTransitionDelegate (CoreGraphics.CGRect startFrame)\n    {\n       this.startFrame = startFrame;\n    }\n\n    public override UIPresentationController GetPresentationControllerForPresentedViewController (UIViewController    presentedViewController, UIViewController presentingViewController, UIViewController sourceViewController)\n    {\n        return new LessonOptionsPresentationController(presentedViewController, presentedViewController);\n    }\n\n    public override IUIViewControllerAnimatedTransitioning GetAnimationControllerForDismissedController(UIViewController dismissed)\n    {\n        return null;\n    }\n\n    public override IUIViewControllerAnimatedTransitioning GetAnimationControllerForPresentedController(UIViewController presented, UIViewController presenting, UIViewController source)\n    {\n       var transitioning = AnimationTransitioning;\n       transitioning.IsPresentation = true;\n       return transitioning;\n    }\n}<\/pre>\n<h3>Conclusion<\/h3>\n<p>Using\u00a0custom transitions and animations\u00a0is an\u00a0easy way to make your app stand out in the Apple App Store and take your app to the next level. To learn more about the animation APIs available for iOS, check\u00a0out our <a href=\"http:\/\/developer.xamarin.com\/recipes\/ios\/animation\/coreanimation\/\">documentation<\/a>.\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last month, I wrote a blog post\u00a0on creating beautiful animations using iOS APIs. Subtle use of animations and transitions in iOS can turn an average\u00a0app into a five-star app. iOS has many built-in transitions between views that can be leveraged as a great starting point for adding animations to your iOS apps. However, with just [&hellip;]<\/p>\n","protected":false},"author":1929,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6,4],"class_list":["post-19177","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-ios","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Last month, I wrote a blog post\u00a0on creating beautiful animations using iOS APIs. Subtle use of animations and transitions in iOS can turn an average\u00a0app into a five-star app. iOS has many built-in transitions between views that can be leveraged as a great starting point for adding animations to your iOS apps. However, with just [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/19177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/1929"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=19177"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/19177\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=19177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=19177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=19177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}