如何使用资产目录颜色集?

我通常使用自定义 UIColors 在 iOS 上使用扩展与 Swift,但现在与 iOS 11/Xcode 9我们可以创建颜色集。我们怎么利用他们?

更新-提示

正如@C ur 所说,我们可以拖放颜色,并像使用 UIColor 对象一样使用它,一个可能的解决方案是将它作为一个扩展:

UIColor as an extension

或者作为一个常数:

UIColor as a constant

现在我想知道我们是否可以像 UIImage 访问资产图像那样访问它们,比如:

UIImage(named: "image-name") -> UIColor(named: "color-name")
70498 次浏览

(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.

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.

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).

 // iOS
let color = UIColor(named: "SillyBlue")


// macOS
let color = NSColor(named: "SillyBlue")

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)

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)

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

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

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.

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

Color("background")

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")
}

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