SwiftUI Custom Units / Dimensions
- Troy Husted

- Oct 23, 2024
- 2 min read
Swift provides a fairly comprehensive set of units and measurements out of the box, but sometimes you need to do calculations between units that aren't natively a part of Swift. To check out what Swift is currently supporting, we can look at their Units and Measurement page.
In this example, I'll show you how you can add your own units and measurements in just a few lines of code, and we'll use units for momentum to show how this is possible.
First, we'll need to define a Dimension class:
class UnitMomentum: Dimension {
} |
To keep the naming consistent between our own custom Units and Swift's native units, we'll call this class UnitMomentum, and its type is Dimension.
To actually set this up, we'll first need to create a base unit. This base unit is used any time we convert between units within UnitMomentum. For example, we may want to convert between newton-seconds (N*s) and kilonewton-seconds (kN*s). Let's define newton-seconds as our base unit:
class UnitMomentum: Dimension { static let newtonseconds = UnitMomentum(symbol: "N*s", converter: UnitConverterLinear(coefficient: 1.0)) override class func baseUnit() -> Self { return newtonseconds as! Self } } |
A few things happened here:
1) We defined newtonseconds with a symbol and a converter
2) We created a func for returning the base unit of UnitMomentum
The symbol is what you might display to the user in order to show the Unit, and the converter is the value that will be multiplied when going to/from the base unit. So, because newtonseconds is the base unit, it has a coefficient of 1 (multiply newton-seconds by 1 to get newton-seconds).
Let's add kilonewton-seconds:
class UnitMomentum: Dimension { static let newtonseconds = UnitMomentum(symbol: "N*s", converter: UnitConverterLinear(coefficient: 1.0)) static let kilonewtonseconds = UnitMomentum(symbol: "kN*s", converter: UnitConverterLinear(coefficient: 1000)) override class func baseUnit() -> Self { return newtonseconds as! Self } } |
We altered the symbol for the new unit, and changed the converter coefficient. In this case, if we want to go from kilonewton-seconds to newton-seconds, we will multiply kilonewton-seconds by 1000 (there are 1000 N*s in 1 kN*s). If instead you were going from newton-seconds to kilonewton-seconds, swift knows to use the reciprocal of your coefficient. It's important to define a good base unit because you will create your coefficients off of just your base unit.
That's it! You can now add any additional conversions to your UnitMomentum class or create an entirely new Unit yourself.
Comments