Whilst the code below worked previously, it has stopped working in Xcode 8 Beta 4, presumably because the components
return was a very un-Swift-y C-array of floats, and has been removed. The error is bald - "'components' is unavailable" - and I can't find what has replaced it, if anything. Does anyone know how to produce the same functionality?
public var cgColour: CGColor {
get {
return CGColor(red: self.colourRed, green: self.colourGreen, blue: self.colourBlue, alpha: self.colourAlpha)
}
set {
let comps = newValue.components // No longer available
self.colourRed = (comps?[0])!
self.colourGreen = (comps?[1])!
self.colourBlue = (comps?[2])!
self.colourAlpha = (comps?[3])!
}
}
Update @Hamish's answer works, but my original intent was not to use UIColor nor NSColor so that my code works in both iOS & MacOS. What I've ended up doing is this...
#if os(iOS)
import UIKit
#elseif os(OSX)
import Cocoa
#endif
extension CGColor {
var components: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var r: CGFloat = 0
var g: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
#if os(iOS)
UIColor(cgColor: self).getRed(&r, green: &g, blue: &b, alpha: &a)
#elseif os(OSX)
NSColor(cgColor: self)?.getRed(&r, green: &g, blue: &b, alpha: &a)
#endif
return (r, g, b, a)
}
}
// Playground code to test...
#if os(iOS)
let rgba = UIColor.brown.cgColor.components //(0.6, 0.4, 0.2, 1.0)
#elseif os(OSX)
let rgba = NSColor.brown.cgColor.components //(0.6, 0.4, 0.2, 1.0)
#endif
... this is such a kludge - has anyone got a better answer?
@Hamish's answer works, but my original intent was not to use
UIColor
orNSColor
so that my code works in both iOS & MacOS. @LeoDabus suggested usingSKColor
, but that's just a type alias to eitherNSColor
orUIColor
, and doesn't have a direct init fromCGColor
anyway, however, Leo's suggestion prompted me to refine my kludge usingCIColor
instead:This looks like a transitional beta issue.
The Swift repo on Github includes an extensive SDK overlay for CoreGraphics, including a new version of
CGColor.components
whose return type is a Swift array instead of anUnsafePointer
. Part of how they make that SDK overlay work is API notes, which map some of the underlying C calls to double-underscore'd Swift methods so that the overlay can wrap them in a more-Swifty interface.It looks like the beta 4 and beta 5 compilers picked up the API notes change, but not the overlay that includes the new version of
components
. Presumably a future beta (or the final Swift 3.0 / Xcode 8.0 release) will include everything that's now on github.I'm also a little perplexed as to why they have removed the
components
property fromCGColor
, as there doesn't seem to be any kind of obvious replacement method/property.It looks like they're trying to get people to use the higher level(As @rickster has discovered, this looks more like a simple transitional issue).UIColor
orNSColor
classes instead.One solution, as you're working with RGB colors, would be to simply wrap your
CGColor
in aUIColor
/NSColor
, and then use thegetRed(_:green:blue:alpha:)
method to get out the components instead.Perhaps not the most ideal solution – would certainly be interested to know if anyone else has a better one, or knows more about this change. Depending on the usage of this property, you may also want to consider simply making it of type
UIColor
/NSColor
to prevent the needless wrapping that this solution requires.I may be mistaking something, but you can find this in the imported header of CGColor.
Isn't this what you are looking for?
I can write something like this:
It works as I expect, but I'm not sure it's as you expect, or Apple would treat this as using a private API. (Apple's latest documentation of
CGColor
does not contain double-underscore leaded symbols.)