Christian Giacomi

An attempt at a small developer blog

Fontawesome 5 in iOS as a UIImage

Posted at — Jun 15, 2019

I love Fontawesome, I have been using them for many years in various web projects. I have always found the icons to be elegant and easy to embed in my web projects.

So when I first needed icons for an iOS app I was working on I found myself at a loss, what should I use? Of course there are tons of different icon libraries out there but somehow none are what I was looking for.

The more I looked at Fontawesome the more I realized that I needed to find a way to use the font in my project. I bought a license for the latest version which is very cool, I love the duotone icons, and I am glad to pay for a product I use and one that is so well crafted. I am still very happy to support Dave Gandy and his team.

So once I decided to go with Fontawesome I started looking around at a way to use it in iOS. Luckily for me I found this really simple tutorial. I was happy again, I could use my favorite icons and I was coding in Swift, what could be better?

Unfortunately I soon ran into a huge limitation, the icons are of course a Font, which means I can use them inside UILabels. Just set the font correctly, include the font in the project and voil√° done. But unfortunately contextual menus in UITableViews don’t support UILabels as child components for a UIContextualAction.

A UIContextualAction can contain an image of type UIImage but that’s it, nothing more. So how do you go from a font to a UIImage in iOS using Swift 4? If you search on Google you will find several solutions, and a couple of github projects, but they where not what I was looking for.

The UIContextualAction is instantiated at runtime, which means that unless the user swipes right or left on a UITableView row, the icon will never be needed. So I decided not to use any of the solutions I found. I decided I needed a simpler solution.

Here is what I came up with and it works perfectly for what I need. The cost of creating a UIImage at runtime is offset by the number of times it might be performed by the user during a session.

I created a class, which contains a method that takes a simple char, color and size and returns the corresponding Fontawesome icon as a UIImage.

import Foundation
import UIKit

class FontAwesomeConverter {
    
    public static func image(fromChar char: String,
                             color: UIColor, 
                             size: CGFloat) -> UIImage {
        // 1.
        let label = UILabel(frame: .zero)
        label.textColor = color
        label.font = UIFont(name: "Font Awesome 5 Pro", size: size)
        label.text = char
        // 2.
        label.sizeToFit()
        
        // 3.
        let renderer = UIGraphicsImageRenderer(size: label.frame.size)

        // 4.
        let image = renderer.image(actions: { context in
            // 5.
            label.layer.render(in: context.cgContext)
        })
        
        return image
    }
}

The code is very readable but basically: 1) I create a UILabel and set the corresponding properties for the icon I would like to convert. 2) Set the size of the label automatically based on the actual icon. 3) Create a UIGraphicsImageRenderer used to create the UIImage. 4) Create an image passing the drawing actions as a trailing closure. 5) Render the UILabel layer and its sublayers into the graphic context.

And you can now use this helper class like so

 UIImage image = FontAwesomeConverter.image(fromChar:"\u{f085}", color: UIColor.white, size: 30.0)

Which will convert the Fontawesome icon of your liking into a UIImage at runtime.