Using icon fonts with Xamarin.Forms

Nikola Irinchev
4 min readNov 5, 2015

I’ve recently started working on a Xamarin.Forms project and it’s been fun and educational for the most part. Still, as with any new technology, there’s much room for improvement. One such area is using icon fonts. It’s rather obvious — when you have a cross platform project, the last thing you want to be dealing with is resizing images and placing them in specific folders for each platform. The web has had it for years, native apps have had it a little less than that, so I was disappointed to see that the Xamarin documentation is suggesting I place 17 versions of each image for each device size and pixel density in 13 different folders throughout my solution. Yikes.

So, without further ranting, let’s see how we could use Font Awesome or something similar to take care of the icons in our application (keep in mind that, while the title says Xamarin.Forms, this is perfectly applicable to Xamarin.iOS and Xamarin.Android projects). For each platform there are three steps we need to perform:

  1. Create a helper to convert a character to a native image.
  2. Create a custom class that will display the image (optional).
  3. Create a custom renderer to glue 1. and 2.

The iOS part

Let’s start with iOS since it’s definitely more pleasing to work with.

0. Adding the font

This is nothing new, but I decided to include it for the sake of completeness. First, add the .ttf to your iOS project’s Resources folder. Then add the following to your Info.plist:

<key>UIAppFonts</key>
<array>
<string>MyIconFont.ttf</string>
<string>MyOtherIconFont.ttf</string>
</array>

Of course, replace with your font names and mind the casing.

1. Creating the helper

Our first real task is to convert an icon font character to native image. For that, I took inspiration from the great FontAwesome+iOS library and created a fairly simple conversion helper:

It only has one method that returns a UIImage from a font with a specified color and size. I’ve defaulted to Ionicons as I find it more visually appealing than Font Awesome, but you can use any font you like. If you notice, we’re specifying the image size, which means we need to do some guesswork to find the right font size. This undoubtedly sacrifices performance for convenience, so if you find it negatively affects your app, you can extract a simpler method that accepts the font size as argument.

2. The custom class

One common scenario, I’m using icon fonts for, is the tab bar icons. It’s simply too annoying to supply selected/unselected images in a bunch of different resolutions. So how do we deal with that? I decided to create an interface that will supply the tab icons that will be set in our custom renderer.

Then, all that’s left is for the child pages to implement the interface.

3. The TabbedPageRenderer

And the final step is to create a TabbedPageRenderer that will check the children for ITabPage implementors and assign the correct icons for the tab bar. Just be sure to do the check after the ViewControllers have been added to the TabBarController.

As you can see, nothing fancy here, we use some Linq to find the pages and set their desired icons for the tabs.

The end result is something similar to this:

The final result :)

The Android part

Now that we have a fancy iOS tab bar, let’s look at the Android side of things.

0. Project setup

Similar to iOS, we have a straightforward setup process — we simply drag the .ttf’s to the Assets folder and set the Build Action to AndroidAsset.

1. Creating the Drawable

Just like with iOS, I didn’t invent the wheel for Android, so I took inspiration from Android-Iconics and created a very simple FontDrawable:

Just like with iOS, this provides us with a basic mechanism to create a drawable with specific color and size from a font icon.

2. The custom class

Let’s just reuse the ITabPage interface, this post has become long enough as it is :)

3. The Renderer

With Android, the approach is slightly different — instead of creating a renderer for the TabbedPage, we have to create a renderer for the child pages instead. Here’s a general-purpose renderer that handles ContentPages:

What it does is to simply check if it is rendering an ITabPage implementor and if it is, it tries to set the icon on the ActionBar. And here’s how a similar setup looks on Android (I apologize for the poor quality, but I only had a simulator lying around):

Conclusion

As we’ve seen, once we have the platform-specific font-to-image converters, it’s fairly simple to create a custom renderer and start using font icons in our Forms application. The great thing is that now those can be used everywhere — the tab bar, in listviews, as navigation bar buttons, you name it. This relieves pressure from the design team and allows us to use high quality vector graphics for our icon needs.

PS: if you need the complete sample, you can find it on GitHub.

--

--

Nikola Irinchev

Software developer currently cruising the streets of Copenhagen on my trusty bike. Giving my all to ensure people love using Realm.