Transition animations on iOS with Xamarin.Forms
Xamarin.Forms allows developers writing beautiful mobile and desktop applications in no time. It is possible to create components once, layout components once, animate components only once! Its performance and stability has improved, so it is, indeed, almost perfect! There are only a few tricky things that are really hard to implement using this framework. One of the most demanded is transition animations between Pages.
Is it even possible to write such things with Xamarin.Forms? Sure! If you are a really impatient person just grab the source code from this repo:
On iOS the default presentation animation looks like a simple right-to-left slide to the new Page from the current one. Unfortunately there are not so many things we can do with this. You may try to mimic Pages with Views and animate transitions between them, but you don’t want this, really (believe me, I was there). Although you may mimic transition animations with Page’s OnAppearing/OnDisappearing lifecycle methods and again — animate Views in Pages. This solution implementation is described on Xamarin Forum, but there is one more way — native animations!
Let’s write an app
Let’s grab images and texts from the Wikipedia and create a simple application for The Beatles fans. It will have only 2 Pages. The first one will contain a grid with musicians photo and name. The second page will display a short bio of selected beatle. You may grab the starter project from https://github.com/OlexaLe/BeatleApp/tree/master/BeatlesApp-start.
When you run it on your device you will see this:
So how to make it less standard?
Modal and regular navigation behave differently and hence its customization is different too. Let’s focus on regular navigation for now.
In native iOS you can implement custom transition animations in 2 steps:
- Implement animator object which adopts the UIViewControllerAnimatedTransitioning protocol
- Adopt UINavigationControllerDelegate protocol to return animator object
Our first custom transition animation will be really simple. Let’s just remove this right-to-left transition from navigation and show new page above current with transparency effect.
In order to do that let’s follow our initial plan and implement animator object:
Now let’s use animator object in UINavigationControllerDelegate:
And the last thing — let’s create NavigationPage renderer. In order not to bother with inheritance and custom controls I will just replace default NavigationPageRenderer with the following one:
That’s it! No changes in the Core part at all! When you run the app you will see this:
Niiiice, but you may use your imagination and create even more exciting animator class. For example, let’s add a zoom effect!
First of all we need to know which image user tapped on, so let’s assign unique identifiers to images. We can do that in many ways. The correct one might be to extend UI components with TransitionId field (inheritance or attached properties to the rescue), but just to illustrate you the pattern I will use Effect that assigns UIKit’s Tag field of UIView.
Now we are able to search through view hierarchy for the view with default UIKit’s method ViewWithTag! Let’s store the id of image user tapped on. I don’t like the idea to have Xamarin.Forms-specific code in pure UIKit objects, so let’s add a new TransitionId field to AnimationNavigationControllerDelegate and set it in AnimationNavigationRenderer.
Booo-boooooo!! I used MessagingCenter here. Sorry, but it is the simplest and the shortest way. Forgive me if you can and let’s move on further. Now we need to send this event. To do that we will modify OpenDetails method like that:
Everything is ready for our new custom animation object implementation. Now the most interesting part:
It is huge, it is complicated, it is ugly. But look what we have now!
The core part of the app was almost not changed, the main complexity stays in animator object, but you can write it once, wrap it in a library and reuse in your other projects.
It is easy to create complex animations in Xamarin.iOS projects, but as you can see in Xamarin.Forms overhead is really big. On the other hand, it’s quite easy to create plain animations, therefore this might be a good way to improve UX of your app with ease.