SwiftUI: Displaying Mathematical Fractions
Situation
Recently, I was faced with the problem of displaying mathematical fractions in a SwiftUI app. Of course, it would have been easy to take a shortcut and be done with it: Text("1/2")
But aesthetically, this really wasn't the way I wanted to go. What I wanted to achieve was something more appealing — closer to the way you would display a fraction in handwriting. Unfortunately, SwiftUI does not offer any method to convert a given fraction to a Text() view.
The first alternative solution that popped into my head seemed straightforward: Unicode symbols. But as you will see it isn’t as easy as it might seem in the beginning.
Complication
When looking up Unicode symbols, you’d quickly see that there are in fact, dedicated symbols for mathematical fractions. However, these cover just some of the most frequently used ones, such as ½, ¼, or ¾. So that doesn’t really help in my use case where I want free full flexibility. I want trickier fractions like “237/81”.
Without the option to rely solely on pre-defined Unicode fractions, there is really just one option left: constructing the whole fraction step by step. Fortunately, Unicode provides the individual symbols needed: superscript numbers, subscript numbers, and a fraction separator.
Note that the codes follow a very similar structure with a weird exception for the superscript 1, 2, and 3. If you want to know why that is, go to Wikipedia.
Solution
Now let's get to work! — Here is what we will do:
Step 1
Create two extensions on the swift type “Int” that give us either a superscript or a subscript string for a given integer. To achieve this, we have to do the following:
- Create a dictionary that maps a single-digit integer (key) — that we will store as a string — to the respective Unicode code in the following notation:
\u{CODE}
- Convert the given integer into a string over which we can iterate and create a concatenated string of Unicode codes
- Return the concatenated string of Unicode codes to get either a superscript or subscript number in string-form
Step 2
Create a method that takes two integers, joins them with a fraction separator, and returns a fraction as a string. Specifically, we do the following:
- Take the first parameter (dividend) and get the respective superscript string
- Add the Unicode code for a fraction separator to that string
- Take the second parameter (divisor), get its subscript string, and add it to the dividend and the separator
- Return the resulting concatenated string to add it in a SwiftUI Text() view
The result will be fractions like the fractions below (have a look at this articles main image to see more examples):
⁷⁄₁₁ ⁶⁄₃₄ ⁷⁰⁄₂
Have a look at the code below and let me know what you think!
Limitations
Please note that the look of the result might vary, depending on the font that you use for your SwiftUI view. While it looks great when using Apple’s SF Pro font family, there might be visual glitches, when using other fonts.