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.