Last active
October 11, 2022 02:56
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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