Skip to content

Instantly share code, notes, and snippets.

@mergesort
Last active October 11, 2022 02:56
Show Gist options
  • Save mergesort/a0d6f0c1297486f0905a7454014a1a64 to your computer and use it in GitHub Desktop.
Save mergesort/a0d6f0c1297486f0905a7454014a1a64 to your computer and use it in GitHub Desktop.
Color to UIColor conversion that preserves light/dark mode support for asset catalog backed colors
// Problem: Converting a Color to UIColor via the UIColor(Color) initializer does not properly respect dark/light mode.
// This becomes an issue when you have a color palette that provides different colors for dark and light mode, for example a red that's rendered darker in dark mode.
// This came up because I use asset catalogs for my apps color palettes, if you'd like to learn how to make slick SwiftUI color palettes check out: https://build.ms/2021/08/24/creating-slick-color-palette-apis
///////////////////////////
// Solution: This extension
///////////////////////////
public extension Color {
var uiColor: UIColor {
let matchingAssetCatalogColor = try? Regex("(?:name = )(.*)(?=>)", as: (Substring, Substring).self)
if let match = try? matchingAssetCatalogColor?.firstMatch(in: self.description) {
return UIColor(named: String(match.output.1), in: Bundle.module, compatibleWith: nil)!
} else {
return UIColor(self)
}
}
}
// Now you can convert from Color to UIColor by calling Color.primary.uiColor, and it will choose the right color from your asset catalog regardless of if you're in light or dark mode.
// If future versions of Color.description change (which I don't think is a big risk) and the regex fails, it will fallback to a safe default of conversion using UIColor(Color), losing dynamism but preserving a good enough user experience.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment