Search code examples
iosswiftui

What's the best way to declare Color for SwiftUI


What's the best way to declare Color for SwiftUI ?

I've ColorSet.xcassets and I need to provide some class or enum or extension that easiest to use with components.

import SwiftUI

extension Color {

    public static let baseGrayLight = Color("baseGrayLight")
    public static let baseGrayMedium = Color("baseGrayMedium")

}

I think extension may be the best way because it doesn't need to class name everywhere to use. But it doesn't work in SwiftUI because component's arguments aren't only Color.

  • fill() required FillStyle
  • foregroundColor() required Color ✅

I'm not sure others function that may require others class. How it should be ? What's class type I need to use ?

enter image description here

I need some standard to help me to resolve this issues.


Solution

  • If your goal is to avoid writing the name of the enclosing type (e.g. Color) all the time, you can write it as an extension of ShapeStyle where Self == Color:

    extension ShapeStyle where Self == Color {
        static var fooColor: Color {
            Color("foo")
        }
    }
    

    Since Xcode 15, extensions like this can be automatically generated from the colors in the asset catalog if you set these build settings:

    enter image description here

    Note that when you write e.g. fill(.red), you are calling this overload, taking a ShapeStyle, and optionally a FillStyle. Do not confuse this with the overload that takes only a FillStyle.

    You don't need to worry about "others function that may require others class", because there is no "others class" [sic]. Color only conforms a fixed set of protocols. Of those, only ShapeStyle declares the built-in color constants.

    You don't need to redeclare these again in a Color extension, because Color conforms to ShapeStyle.

    By declaring your custom colors in ShapeStyle, you ensured that everywhere you can use a built-in color without the Color. prefix, you can use your own custom color without the Color. prefix.