Adam
Adam

Reputation: 1913

How can I programmatically obtain all colors included in Color Assets catalog?

I have a color asset catalog with my custom colors. Is there a way to get and display them in the application? Something like this

func getColorsFromAssetCatalog() -> [UIColor]? {
      //Somehow return those colors
}

let colorsInCatalog = getColorsFromAssetCatalog()

for color in colorsInCatalog {
       // Do something
}

Upvotes: 2

Views: 2809

Answers (5)

THUB
THUB

Reputation: 314

With Xcode 14.2 it seems there is still no functionality that can programmatically obtain colors included in Color Assets Catalog.

However, I had the same requirement and I have used SwiftGen (https://github.com/SwiftGen/SwiftGen) to convert my color assets into Swift5 source code in a preprocess.

xcassets:
  inputs: /dir/to/search/for/imageset/assets
  outputs:
    templateName: swift5
    output: Assets.swift

See https://github.com/SwiftGen/SwiftGen#asset-catalog for the example given.

Once I add or modify colors, I run swiftgen to update my source file and I can access all my assets programmatically with some helper functions as described in the other answers.

Upvotes: 1

satyen maurya
satyen maurya

Reputation: 19

Make an extension of UIColor, like below:

extension UIColor {
    public class var appBackgroundColor: UIColor { UIColor(named : "appBackgroundColor") ?? UIColor.white }
}

Now you can easily access it throughout your app using just:

UIColor.appBackgroundColor

Only drawback is that you have to add color to asset and also in the extension

Upvotes: 0

staticVoidMan
staticVoidMan

Reputation: 20234

Currently there is no way to request the Asset Catalog to programmatically tell you what all assets it contains. i.e. there's no API, imho, that will let you fetch the color names (or other asset names) you have added in the Asset Catalog.
You can, ofcourse, fetch the color/asset if you already know the name.

Furthermore, the asset catalog compiles into Assets.car which is unreadable so attempts to read that file are also futile.

Anyways... coming back to your case, you would have to manually maintain some mechanism like an Enum to track the colors.


Solution:

  • Add a color to Asset Catalog; say named "WeirdOrange"
  • Use an Enum to maintain your custom color names, like:

    enum Colors: String {
        //... previous cases
        case weirdOrange = "WeirdOrange" //... now we add this one
    }
    
  • Use it in the app as:

    UIColor(named: Colors.weirdOrange.rawValue)
    

Example:

Lets fine-tune it a bit more for your purpose:

enum Colors: String, CaseIterable {
    case funkyMunky = "FunkyMunky"
    case weirdOrange = "WeirdOrange"
    case popBlue = "PopBlue"
    case murkyPoo = "MurkyPoo"

    static var assetCatalogued: [UIColor] {
        return self.allCases.compactMap { (colorCase) -> UIColor? in
            return UIColor(named: colorCase.rawValue)
        }
    }
}

for color in Colors.assetCatalogued {
    //Do something
    print(color)
}

NOTE:

  • To run the example, either change the color names or add colors with the given names, else Colors.assetCatalogued will not return any UIColors
  • Used CaseIterable for .allCases
  • You would have to manually add/remove a case when adding/removing the related color asset

Upvotes: 3

Robert Dresler
Robert Dresler

Reputation: 11140

I think you'll have to get them manually like

UIColor(named: "Color1")
UIColor(named: "Color2")
...

So, I would suggest you to create custom struct with static constant for colors and all cases of colors

struct Color {

    static let allCases = [Color.color1, Color.color2, ...]

    static let color1 = UIColor(named: "Color1")!
    static let color2 = UIColor(named: "Color2")!
    ...
}

Then you can get all your colors from Color Set in xcassets catalog by getting

Color.allCases

Upvotes: 0

Pooja Kamath
Pooja Kamath

Reputation: 1298

You can get the color from asset using this

let color = UIColor(named: "MyCustomColorName")

You can declare an enum of custom colors you support

enum CustomColors
{
   case CustomYellow
   case CustomRed
}

and within a switch case you can pass the color from the assets like this:

   switch(CustomColorName)
   {
       case CustomYellow : 
        return UIColor(named: "MyCustomColorName")
    }

Upvotes: 0

Related Questions