Skip to content

Instantly share code, notes, and snippets.

@winstondu
Created October 7, 2025 04:22
Show Gist options
  • Select an option

  • Save winstondu/a0625acc4c350a89bd7146e385a9a235 to your computer and use it in GitHub Desktop.

Select an option

Save winstondu/a0625acc4c350a89bd7146e385a9a235 to your computer and use it in GitHub Desktop.
Hex extension for Color
//
// Color+Hex.swift
//
import SwiftUI
extension Color {
// MARK: - Private Helpers
/// Parses a sanitized 6-digit hex string (RRGGBB) into normalized RGB components.
/// - Parameter hexSanitized: Hex string without leading '#', must be exactly 6 characters.
/// - Returns: Tuple of (red, green, blue) in 0.0...1.0 if parsing succeeds; otherwise nil.
private static func rgbComponents(fromSixDigitHex hexSanitized: String) -> (
red: Double, green: Double, blue: Double
)? {
guard hexSanitized.count == 6 else { return nil }
var rgb: UInt64 = 0
guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil }
let red = Double((rgb >> 16) & 0xFF) / 255.0
let green = Double((rgb >> 8) & 0xFF) / 255.0
let blue = Double(rgb & 0xFF) / 255.0
return (red, green, blue)
}
public init?(hex: String) {
var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
// Remove hash if it exists
if hexSanitized.hasPrefix("#") {
hexSanitized.remove(at: hexSanitized.startIndex)
}
// Support 6-digit (RRGGBB) and 8-digit (RRGGBBAA) hex strings
if hexSanitized.count == 8 {
let alphaHex = String(hexSanitized.suffix(2))
let rgbHex = String(hexSanitized.prefix(6))
var alphaInt: UInt64 = 0
guard Scanner(string: alphaHex).scanHexInt64(&alphaInt) else { return nil }
let alpha = Double(alphaInt) / 255.0
guard let comps = Color.rgbComponents(fromSixDigitHex: rgbHex) else { return nil }
self.init(.sRGB, red: comps.red, green: comps.green, blue: comps.blue, opacity: alpha)
return
} else if hexSanitized.count == 6 {
guard let comps = Color.rgbComponents(fromSixDigitHex: hexSanitized) else { return nil }
self.init(red: comps.red, green: comps.green, blue: comps.blue)
return
} else {
// Invalid length
return nil
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment