top of page

Storing Color in UserDefaults

  • lioneldude
  • Aug 31
  • 2 min read

A color picker is a simple but powerful way to let users personalize your app. With just a few lines of SwiftUI code, you can allow them to choose their favorite colors. Since Color itself cannot be stored directly in UserDefaults, we convert it into a hex string and save it using @AppStorage.


UserDefaults is a natural fit here because it’s designed for lightweight user preferences — things like toggles, theme settings, or last-used values. It saves the data directly on the device’s local storage, which makes it fast and reliable without needing a database. However, UserDefaults only supports a limited set of data types (like Int, Bool, Double, String, or Data). That’s why converting a Color into a hex string is the simplest way to make it persist.



Why use a Color Picker?


Adding a color picker gives your users quick control over the theme, background, or highlight colors. It’s an easy way to make the app feel more personal and engaging.


SwiftUI Color Picker
Color Picker

Use a color picker by calling the ColorPicker() API, where:

structure ColorPicker<Label> where Label : View

Example code:

// supportsOpacity is optional, defaults to true
ColorPicker("Select a Color", selection: $selectedColor, supportsOpacity: true)
    .onChange(of: selectedColor) { _, newColor in
        colorHex = newColor.hexString
    }

  • The ColorPicker displays the system’s native picker UI.

  • The selection is stored as a hex string in @AppStorage.

  • A helper extension handles conversion between Color and hex strings (shown below).

  • The onChange modifier is used to react to updates whenever the user picks a new color, so the stored hex string always stays in sync.



Extension for Color, remember to Import SwiftUI.

/// Extension to Color with helpers to convert from Color to hex string and back
extension Color {
    // Convert SwiftUI Color into hex string format
    var hexString: String {
        let uiColor = UIColor(self)
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        
        // Get the components that form the color in the RGB color space
        uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        
        // e.g. #FF0000FF
        return String(format: "#%02X%02X%02X%02X",
                      lroundf(Float(red * 255)),
                      lroundf(Float(green * 255)),
                      lroundf(Float(blue * 255)),
                      lroundf(Float(alpha * 255))) // Include alpha component, opacity from 0 to 1
    }
    
    // Convert hex string into SwiftUI Color
    init?(hex: String) {
        var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        
        hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "")
        
        var rgb: UInt64 = 0
        // Read the hex string and convert into a 64-bit unsigned integer
        guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil }
        
        // Use bit masking and shifting to extract red, green, blue and alpha components
        let red = Double((rgb & 0xFF000000) >> 24) / 255.0
        let green = Double((rgb & 0x00FF0000) >> 16) / 255.0
        let blue = Double((rgb & 0x0000FF00) >> 8) / 255.0
        let alpha = Double(rgb & 0x000000FF) / 255.0
        
        self.init(.sRGB, red: red, green: green, blue: blue, opacity: alpha)
    }
}

This way, the chosen color is saved in UserDefaults and automatically restored when the app relaunches.



See More


Comments


bottom of page