Swift, SwiftUI – .getRed(&red, green: &green, blue: &blue, alpha: &alpha)

I am following Stanfords’ CS193p Developing Apps for iOS online course.

I’m trying to do the Assignment 6 Memorize.pdf.

It says to use this code below ⬇️, but it gives me always white color. Is there a bug somewhere? Please help.

import SwiftUI

struct RGBAColor: Codable, Equatable, Hashable {
    let red: Double
    let green: Double
    let blue: Double
    let alpha: Double
}

extension Color {
    init(rgbaColor rgba: RGBAColor) {
        self.init(.sRGB, red: rgba.red, green: rgba.green, blue: rgba.blue, opacity: rgba.alpha)
    }
}

extension RGBAColor {
    init(color: Color) {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        if let cgColor = color.cgColor {
            UIColor(cgColor: cgColor).getRed(&red, green: &green, blue: &blue, alpha: &alpha)
        }
        self.init(red: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha))
    }
}
import SwiftUI

struct ContentView: View {
    static let rgbaColorRed = RGBAColor(color: Color.red)
    static let thisShouldBeRed = Color(rgbaColor: rgbaColorRed)
    
    var body: some View {
        Text("Hello, world!")
            .padding()
            .foregroundColor(ContentView.thisShouldBeRed) // why white here, not red???
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

>Solution :

As the cgColor property’s documentation says:

For a dynamic color, like one you load from an Asset Catalog using init(_:bundle:), or one you create from a dynamic UIKit or AppKit color, this property is nil.

Color.red is actually a dynamic color:

A context-dependent red color suitable for use in UI elements.

So Color.red.cgColor is nil, causing the getRed(_:green:blue:alpha:) call to not run, and the red, green, blue, alpha local variables remain 0. So the color you got is not "white", but "transparent".

You can actually create a UIColor directly from Color, without going through CGColor:

var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0

// note here:
UIColor(color).getRed(&red, green: &green, blue: &blue, alpha: &alpha)
self.init(red: Double(red), green: Double(green), blue: Double(blue), alpha: Double(alpha))

Leave a Reply