Skip to content

Instantly share code, notes, and snippets.

@fpg1503
Created June 7, 2019 22:12
Show Gist options
  • Save fpg1503/e370478e921ffdd4910279b2ccafd327 to your computer and use it in GitHub Desktop.
Save fpg1503/e370478e921ffdd4910279b2ccafd327 to your computer and use it in GitHub Desktop.
Dynamic Color Palettes that resolve immediately on older versions
extension ColorContext {
@available(iOS 13.0, *)
init(_ traitCollection: UITraitCollection,
defaultMode: Mode = .light,
defaultElevation: Elevation = .base,
defaultAccessibilityContrast: AccessibilityContrast = .normal) {
mode = {
switch traitCollection.userInterfaceStyle {
case .light: return .light
case .dark: return .dark
case .unspecified: return defaultMode
@unknown default: return defaultMode
}
}()
elevation = {
switch traitCollection.userInterfaceLevel {
case .base: return .base
case .elevated: return .elevated
case .unspecified: return defaultElevation
@unknown default: return defaultElevation
}
}()
accessibilityContrast = {
switch traitCollection.accessibilityContrast {
case .normal: return .normal
case .high: return .high
case .unspecified: return defaultAccessibilityContrast
@unknown default: return defaultAccessibilityContrast
}
}()
}
}
struct ColorContext {
enum Mode {
case light, dark
}
enum Elevation {
case base, elevated
}
enum AccessibilityContrast {
case normal, high
}
let mode: Mode
let elevation: Elevation
let accessibilityContrast: AccessibilityContrast
}
protocol TraitCollectionProvider {
var traitCollection: UITraitCollection { get }
}
extension UIView: TraitCollectionProvider { }
extension UIViewController: TraitCollectionProvider { }
extension UIColor {
func backwardsCompatibleResolvedColor(with traitCollection: UITraitCollection) -> UIColor {
guard #available(iOS 13.0, *) else {
return self
}
return resolvedColor(with: traitCollection)
}
}
extension UIColor {
func cgColor(for provider: TraitCollectionProvider) -> CGColor {
let traitCollection = provider.traitCollection
return backwardsCompatibleResolvedColor(with: traitCollection).cgColor
}
func ciColor(for provider: TraitCollectionProvider) -> CIColor {
let traitCollection = provider.traitCollection
return backwardsCompatibleResolvedColor(with: traitCollection).ciColor
}
}
extension UIColor {
static func dynamicColor(provider: @escaping (ColorContext) -> UIColor,
defaultMode: ColorContext.Mode = .light,
defaultElevation: ColorContext.Elevation = .base,
defaultAccessibilityContrast: ColorContext.AccessibilityContrast = .normal) -> UIColor {
guard #available(iOS 13.0, *) else {
let colorContext = ColorContext(mode: defaultMode,
elevation: defaultElevation,
accessibilityContrast: defaultAccessibilityContrast)
return provider(colorContext)
}
return UIColor { traitCollection -> UIColor in
let colorContext = ColorContext(traitCollection)
return provider(colorContext)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment