[Xamarin Forms] Embed custom fonts in your apps

Recently I had some difficulties to embed custom fonts in my applications. Specially with the iOS application that was crashing with no message (while it was working for the Android version).
In fact, it was a font issue. So in this post I will show you some tips to embed quickly custom fonts in both your Android & iOS apps.



1- Select your fonts
The first step is to get some cool fonts you want to use. You'll maybe use (free) fonts from various websites like:
www.1001freefonts.com
www.dafont.com



2- Set font files properties
In your solution, include your fonts files:

iOS: 
Create a subfolder (in the the 'Resources' directory) where to embed the fonts
Build Action = BundleResource & "Copy Always"

Android:
Create a subfolder in the 'Assets' directory where to embed the fonts:
Build Action = "AndroidAsset" & "Copy Always"





3- iOS application: edit your plist file
With iOS you need to specify the embedded fonts in your *.plist file:
In your Info.plist file add the following sections (under the <dictsection):

That should be enough for iOS; You don't need to implement any specific renderer.



4- Android: Add a custom Renderer
For Android, in order to apply the font correctly, you will need to implement a custom label renderer.
So you can for instance:
- create a new view in your Forms project: ie. ExtendedLabel
- create the dedicated Android custom renderer, in your Android project

You can find below a sample code:

Extended label control:

public class ExtLabel : Label
{
     ExtLabel()            
     {
          // base for implementing a better label control
     }
}

Android ExtendedLabel renderer:

[assembly: ExportRenderer(typeof(ExtLabel), typeof(ExtLabelRenderer))]
namespace Droid.CustomRenderers
{
    public class ExtLabelRenderer : LabelRenderer
    {
        private object _xamFormsSender;

        public ExtLabelRenderer()
        {
            _xamFormsSender = null;
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            // Update native Textview
            if (_xamFormsSender != sender || e.PropertyName == ExtLabel.FontFamilyProperty.PropertyName)
            {
                var font = ((ExtLabel)sender).FontFamily;

                // valid font 
                if (!string.IsNullOrEmpty(font))
                {
                    // check font file name
                    if (!font.Contains(".ttf")) font += ".ttf";
                    var typeface = Typeface.CreateFromAsset(Forms.Context.Assets, "Fonts/" + font);

                    // update font
                    var label = Control as TextView;
                    if (label != null)
                        label.Typeface = typeface;
                }

                _xamFormsSender = sender;
            }
        }
    }
}



5- Set the font in your Forms.xaml code

Finally you just have to reference your fonts from your forms. With the custom provided renderer, you just need to indicate the font name in the FontFamily property. Sample below:

<CTRL:ExtLabel BindingContext="{x:Reference Name=uiParent}"
   Text="{Binding Text}"
   TextColor="{Binding TextColor}"
   XAlign="Center"
   FontFamily="lato_bold"
   FontSize="Medium"
   LineBreakMode="WordWrap"
   />



Caution !

- Fonts Name:
In iOS, fonts are all loaded when the app starts. Take note that differents fonts file (specially *.ttf) can contain fonts with the same name !

For instance:
- lato_bold.ttf & lato_italic.ttf can both contain a font with 'lato' name.

How to know a font's name ?




This can crash your iOS app ! So I suggest you to rename your fonts using a specific tool like
- Typograf





Comments

Post a Comment

Popular posts from this blog

EMGU with Xamarin Forms guide [part 1]

[Xamarin Forms] Custom bottom bordered entry (iOS & Android)

Xamarin.Forms device unique ID...