Articles, podcasts and news about Swift development, by John Sundell.

Automatic conversions between Double and CGFloat values in Swift 5.5

Published on 15 Jun 2021

New in Swift 5.5: The compiler can now automatically perform conversions between Double and CGFloat values.

Although the two have always been equivalent on 64-bit systems, before Swift 5.5 (which is currently in beta as part of Xcode 13), we had to manually convert between them in order to satisfy Swift’s type system — since they were, and still are, two distinct types as far as the type system in concerned.

However, when using literals, the compiler has always been able to infer what type that each literal should be turned into based on the current context. For example, within the following SwiftUI view, we’re applying both the scaleEffect and opacity modifier without having to specify that the former accepts a CGFloat, while the latter accepts a Double:

struct DecorationImage: View {
    var name: String

    var body: some View {
        Image(name)
            .scaleEffect(0.5) // This is a CGFloat
            .opacity(0.8) // This is a Double
    }
}

But if we instead were to define those two values as properties, then we’d have to explicitly type our scale value as CGFloat — since otherwise it would be interpreted as a Double, and we’d get a compiler error when trying to pass it to the scaleEffect modifier:

struct DecorationImage: View {
    var name: String
    var scale: CGFloat = 0.5
var opacity: Double = 0.8

    var body: some View {
        Image(name)
            .scaleEffect(scale)
            .opacity(opacity)
    }
}

When using Swift 5.5, though, that’s no longer the case — and we can now freely pass Double values to functions that accept a CGFloat, and vice versa. So we could either choose to make both of our properties CGFloat values, or doubles, or (my personal preference) remove the type information entirely and let the compiler infer that they are doubles:

struct DecorationImage: View {
    var name: String
    var scale = 0.5
var opacity = 0.8

    var body: some View {
        Image(name)
            .scaleEffect(scale)
            .opacity(opacity)
    }
}

The good news is that the above doesn’t just work with system APIs, it works with any code or API that uses CGFloat or Double values. A small, but really nice new feature.