core-graphics swift3

core-graphics - cgcolor swift 4



Xcode 8 Beta 4 CGColor.components no disponible (5)

Mientras que el código siguiente funcionaba anteriormente, ha dejado de funcionar en Xcode 8 Beta 4, presumiblemente porque los components devueltos eran una matriz de flotadores muy poco Swift-y, y se ha eliminado. El error es calvo - "''components'' no está disponible" - y no puedo encontrar lo que lo ha reemplazado, en todo caso. ¿Alguien sabe cómo producir la misma funcionalidad?

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])! } }

La actualización de la respuesta de @Hamish funciona, pero mi intención original no era usar UIColor ni NSColor para que mi código funcionara tanto en iOS como en MacOS. Lo que terminé haciendo es esto ...

#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

... esto es un desafío - ¿alguien tiene una mejor respuesta?


La respuesta de UIColor funciona, pero mi intención original no era usar UIColor o NSColor para que mi código funcionara tanto en iOS como en MacOS. @LeoDabus sugirió usar SKColor , pero eso es solo un alias tipo de NSColor o UIColor , y no tiene un init directo de CGColor todos modos, sin embargo, la sugerencia de Leo me llevó a refinar mi CIColor usando CIColor en CIColor lugar:

import CoreImage extension CGColor { var components: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) { let ciColor = CIColor(cgColor: self) return (ciColor.red, ciColor.green, ciColor.blue, ciColor.alpha) } }


Puede que esté confundiendo algo, pero puede encontrarlo en el encabezado importado de CGColor.

/* Return the color components (including alpha) associated with `color''. */ @available(OSX 10.3, *) public var __unsafeComponents: UnsafePointer<CGFloat>? { get }

¿No es esto lo que estás buscando?

Puedo escribir algo como esto:

public var cgColour: CGColor { get { return CGColor(red: self.colourRed, green: self.colourGreen, blue: self.colourBlue, alpha: self.colourAlpha) } set { if let comps = newValue.__unsafeComponents, newValue.numberOfComponents == 4 { self.colourRed = comps[0] self.colourGreen = comps[1] self.colourBlue = comps[2] self.colourAlpha = comps[3] } } }

Funciona como esperaba, pero no estoy seguro de que sea como esperabas, o Apple consideraría esto como utilizar una API privada. ( La última documentación de CGColor de CGColor no contiene símbolos con doble subrayado).


Esto parece un problema beta de transición.

El repositorio de Swift en Github incluye una amplia superposición de SDK para CoreGraphics , incluida una nueva versión de CGColor.components cuyo tipo de devolución es una matriz Swift en lugar de un UnsafePointer . Parte de cómo hacen que la superposición de SDK funcione son las notas de la API , que asignan algunas de las llamadas C subyacentes a los métodos Swift doblemente subrayados para que la superposición pueda envolverlos en una interfaz más Swifty.

Parece que los compiladores beta 4 y beta 5 recogieron las notas de la API cambian, pero no la superposición que incluye la nueva versión de los components . Presumiblemente, una futura versión beta (o la versión final de Swift 3.0 / Xcode 8.0) incluirá todo lo que está ahora en github.


También estoy un poco perplejo sobre por qué han eliminado la propiedad de components de CGColor , ya que no parece haber ningún tipo de método / propiedad de reemplazo obvio. Parece que intentan hacer que las personas usen las clases de nivel superior UIColor o NSColor lugar. (Como @rickster ha descubierto , esto se parece más a un simple problema de transición).

Una solución, ya que está trabajando con colores RGB, sería simplemente envolver su CGColor en un UIColor / NSColor , y luego usar el getRed(_:green:blue:alpha:) para sacar los componentes en su lugar.

public var cgColour : CGColor { get { return CGColor(red: colourRed, green: colourGreen, blue: colourBlue, alpha: colourAlpha) } set { NSColor(cgColor: newValue)?.getRed(&colourRed, green: &colourGreen, blue: &colourBlue, alpha: &colourAlpha) } }

Tal vez no sea la solución más ideal: sin duda estaría interesado en saber si alguien más tiene una mejor, o sabe más acerca de este cambio. Dependiendo del uso de esta propiedad, también puede considerar simplemente hacerla de tipo UIColor / NSColor para evitar el envoltorio innecesario que requiere esta solución.


extension UIColor { var all4Components:(red:CGFloat, green:CGFloat, blue: CGFloat, alpha:CGFloat) { let components = self.cgColor.components! let red = components[0] let green = components[1] let blue = components[2] let alpha = components[3] return (red:red, green:green, blue: blue, alpha:alpha) } }