Can I programmatically switch between asset catalogs?

In my app there is a setting where you can choose either "cat" or "dog". Depending on this setting, all the images in the app should be different: icons, backgrounds, etc

I don't want to create individual outlets for all images and write code that will replace those images. Is there a mechanism that would allow me to conditionally use one set of images or another, depending on my internal variable.

Closest to what I need is iOS asset catalog support for Dark Appearance — all images (including images set via interface builder with no outlets) in my app are magically replaced, depending on app appearance. I want the same behavior, but based on my internal setting.

Upvotes: 5

Views: 1143

Answers (1)

kerim.ba
kerim.ba

Reputation: 286

Switching between asset catalogs programmatically and without is not an option in iOS nor Xcode (at least not in a way as you described), so some workaround has to be used. The reason is that all xcassets in the app bundle are loaded and you can use image in runtime from any of them without an option to specify the asset. It could be achieved by using iOS Resources Bundle and XCAssets:

  • Create Two Resource Bundles, name them as you went, they will represent collection of data for your states.
  • In each of the bundles add the *.xcassets and assign the images
  • Create an enum representing the state(s) of your app

`

enum AppState {

    case dog
    case cat

    var bundle: Bundle {
      switch self {
      case .dog:
        return Bundle(identifier: "com.dog")!
      case .cat:
        return Bundle(identifier: "com.cat")!
    }
}

`

And that is it, voila. You can make your life easier by making extension for image, optionally of course. I image you would use the same image names, only states will change.

extension UIImage {
  func getImage(named: String, state: AppState) {
    return UIImage(named: named, in: state.bundle!)
  }
}

Hope this is what you need.

Upvotes: 1

Related Questions