How can we use Assets Catalog Color Sets?
Asked Answered
R

12

107

I usually use custom UIColors on iOS using extensions with Swift, but now with iOS 11/ Xcode 9 we can create Colors Sets. How can we use them?

Update - Tip

As @Cœur says we can drag&drop de color, and use it like a UIColor object and a possible solution could be use it as a extension:

UIColor as an extension

Or as a constant:

UIColor as a constant

Now I wanna know if we can access them like an UIImage access to an Asset Image or not, like:

UIImage(named: "image-name") -> UIColor(named: "color-name")
Rambutan answered 6/6, 2017 at 18:50 Comment(0)
O
128
UIColor(named: "myColor") 

Source: WWDC 2017 Session 237 —— What's New in MapKit


Caveat: Your project's Deployment Target needs to be set to iOS 11.0.

Objectify answered 9/6, 2017 at 16:28 Comment(1)
This will require Deployment Target = 11.0.Isahella
R
50

In Xcode 11 press command + shift + L , it will open a snippet , select last one like i showed in image drag and drop .

enter image description here

Raimondo answered 23/10, 2019 at 17:15 Comment(5)
Kudos. Never would have thought to check this menu.Lennyleno
It's a nice way to add color literal but if we need to change the color a little using the assets, the change will not reflect in the code where the literal was dragged. Thus I am still looking for solutions that use asset name instead and deal with the optional return type of UIColor.Acetometer
Perfect Way to Add ColorWeirdie
very handy tip, Thanks!Rost
What's the point of using the asset catalog then? You may as well insert the literal in code, because doing this doesn't link the color to the asset catalog, it just pastes a snapshot. Try changing the color in the asset catalog and you'll see your color doesn't changeSatori
G
48

(short answer to the question update: there is UIColor(named: "MyColor") in Xcode 9.0)

Answering the original question:

  1. you create your color set

enter image description here

  1. you find your color among your snippets and you drag-n-drop it

enter image description here

  1. it will translate to a color literal when looking at the source code:

    #colorLiteral(red: 0, green: 0.6378085017, blue: 0.8846047521, alpha: 1)

You notice how the values of red, green and blue are different? It's because I defined them using Color Space Display P3, but the colorLiteral is using Color Space sRGB.

Gehlbach answered 8/6, 2017 at 6:34 Comment(3)
@Rambutan it's a bad practice to edit the question to a different one; see meta.#350809 or meta.stackexchange.com/questions/43478/…Allness
I didn't change the question, I just have specified better the implementation I want: How can I use them, but like we usually use Images Assets coz drag&drop is just one alternative solution. Sorry for the inconvenience.Rambutan
Xcode didn't add UIColor(named:), it's part of UIKit, which is built in to iOS starting with iOS 11. It might seem like a subtle point but it's important. Xcode can't add methods to UIKit.Crucible
R
35

Short Version

Add a colour set to an asset catalog, name it and set your colour in the attributes inspector, then call it in your code with UIColor(named: "MyColor").

Full Instructions

  1. In the asset catalog viewer, click the plus button at the bottom right of the main panel and choose New Color Set

    New Color Set menu

  2. Click on the white square, and select the Attributes Inspector (right-most icon in the right pane)

  3. From there you can name and choose your colour.

    enter image description here

  4. To use it in your code, call it with UIColor(named: "MyColor"). This returns an optional, so you'll need to unwrap it in most cases (this is probably one of the few cases where a force unwrap is acceptable, given you know the colour exists in your asset catalog).

Robbinrobbins answered 30/8, 2017 at 21:0 Comment(4)
This will require Deployment Target = 11.0.Stephanus
How can I do it in iOS <= 10Thorlie
Good answer. I wish iOS would make those assets something you could compile against the same way Android does with R.color.myColor. The new Colors.xcassets approach is definitely better, but still leaves the door open to runtime errors if you mistype a color's name, remove a color without finding all the spots it's used, etc. Seems like something that should be caught at compile time rather than cause a crash at runtime (I get that you can treat it as optional and not force unwrap it, but then that adds more complexity...so then what was the point?!) :)Hagiographa
In iOS < 11.0 you need to use an if #available(iOS 11.0, *) { } else { //Fallback on earlier versions }, etc. set up.Embrocation
L
35

You need to use UIColor(named: "appBlue").

And you can create a function in UIColor extension for simple access.

enum AssetsColor {
   case yellow
   case black
   case blue
   case gray
   case green
   case lightGray
   case separatorColor
   case red
}

extension UIColor {

    static func appColor(_ name: AssetsColor) -> UIColor? {
        switch name {
        case .yellow:
            return UIColor(named: "appYellow")
        case .black:
            return UIColor(named: "appBlack")
        case .blue:
            return UIColor(named: "appBlue")
        case .gray:
            return UIColor(named: "appGray")
        case .lightGray:
            return UIColor(named: "appLightGray")
        case .red:
            return UIColor(named: "appRed")
        case .separatorColor:
            return UIColor(named: "appSeparatorColor")
        case .green:
            return UIColor(named: "appGreen") 
        }
    }
}

You can use it like this:

userNameTextField.textColor = UIColor.appColor(.gray)
Laird answered 30/11, 2018 at 8:3 Comment(3)
Minimum SDKs are: iOS 11.0+, Mac Catalyst 13.0+, tvOS 11.0+, watchOS 4.0Reactivate
You could add raw value for enum AssetsColor: String and provide names as raw values (e.g. case yellow = "appYellow") so you won't need a switch, but just UIColor(named: name.rawValue)Unnerve
How do you resolve the warning Value of optional type 'UIColor?' must be unwrapped to a value of type 'UIColor' for these optional return type UIColor?? What is the default value that we can provide or what is the best way to handle it?Maryjanemaryjo
G
31

You can use this way for simple accessing (swift 4 & swift 5)

enum AssetsColor: String {
    case backgroundGray
    case blue
    case colorAccent
    case colorPrimary
    case darkBlue
    case yellow
}

extension UIColor {
    static func appColor(_ name: AssetsColor) -> UIColor? {
         return UIColor(named: name.rawValue)
    }
}

Using:

userNameTextField.textColor = UIColor.appColor(.blue)
Granulite answered 12/7, 2019 at 21:9 Comment(0)
B
10
 // iOS
 let color = UIColor(named: "SillyBlue")

 // macOS
 let color = NSColor(named: "SillyBlue")
Biannual answered 25/11, 2017 at 10:48 Comment(1)
That URL has nothing to do with asset catalog colors, or colors, or iOS.Crucible
T
7

For your question if you can access color assets like the image using literal, as of Xcode 10.2 you can type in colorliteral, then you can pick the color you want to use that is under your asset manager.

sample snippet

Toastmaster answered 12/11, 2019 at 8:44 Comment(2)
Hi just type-in color literal in your editor. for example: label.textColor = color literalToastmaster
How do you access the color assets like that in Xcode 12.5? I double-clicked the color square "Color Literal" created, then clicked on "Other" in the new pop-up but none of the tabs show the color assets, not even "Color Palettes"'s 5 dropdown options.Kudos
G
3

In case you experience a delay with colors loading in a Swift Package when using UIColor(named:):

The answers above are totally valid for a regular project but if you are using assets in a swift package, you can see a delay when loading the colors when you use UIColor(named: "example_name"). If you use UIColor(named: "background", in: Bundle.module, compatibleWith: .current) overload that is targeting the module, the colors load immediately without any delay.

Note: I experienced this on Xcode 12.1.

Gramineous answered 10/11, 2020 at 11:25 Comment(0)
V
3

for swiftUI create a class and name it : Color+extansion and extend Color :

import SwiftUI

extension Color {
    static let background = Color("BackgroundColor")
    static let whiteColor = Color("WhiteColor")
    static let blackColor = Color("BackgroundColor")
    static let primery = Color("PrimeryColor")
    static let secondaryColor = Color("SecondaryColor")    
}
Vaunting answered 6/9, 2021 at 16:7 Comment(0)
N
3

you can create extension with func for unwrapping colors from assets and use it with every color in your app

extension UIColor {
    static var someColor: UIColor {
        return UIColor.color(name: "SomeColor")
    }

    private static func color(name: String) -> UIColor {
        guard let color = UIColor(named: name) else {
            return .black
        }
        return color
    }
}

usage example:

UIColor.someColor

or

someLabel.textColor = .someColor
Nidus answered 8/8, 2022 at 9:30 Comment(0)
B
2

Or, with the SwiftUI Color structure, you can simply call the initializer with the asset name:

Color("background")
Byssinosis answered 6/9, 2021 at 15:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.