hexadecimal from custom swift uicolor

from - uicolor hexadecimal swift



¿Cómo agregar inicializadores en extensiones a las clases UIKit existentes, como UIColor? (3)

Bueno, si realmente, realmente, realmente quieres anular un inicializador, hay una manera.

Antes de seguir leyendo : nunca hagas esto para cambiar el comportamiento de UIKit . ¿Por qué? Podría confundir a alguien que no puede entender por qué un inicializador UIColor no está haciendo lo que normalmente hace. Solo hazlo para corregir un error de UIKit , o agrega funcionalidad, etc.

He usado lo siguiente para parchear varios errores de iOS.

Código

extension UIColor { private static var needsToOverrideInit = true override open class func initialize() { // Only run once - otherwise subclasses will call this too. Not obvious. if needsToOverrideInit { let defaultInit = class_getInstanceMethod(UIColor.self, #selector(UIColor.init(red:green:blue:alpha:))) let ourInit = class_getInstanceMethod(UIViewController.self, #selector(UIColor.init(_red:_green:_blue:_alpha:))) method_exchangeImplementations(defaultInit, ourInit) needsToOverrideInit = false } } convenience init(_red: CGFloat, _green: CGFloat, _blue: CGFloat, _alpha: CGFloat) { // This is trippy. We swapped implementations... won''t recurse. self.init(red: _red, green: _green, blue: _blue, alpha: _alpha) /////////////////////////// // Add custom logic here // /////////////////////////// } }

Explicación

Esto está utilizando la naturaleza dinámica de Objective-C, llamada desde Swift, para intercambiar los punteros de definición de método en tiempo de ejecución. Si no sabe lo que esto significa, o sus implicaciones, probablemente sea una buena idea leer sobre el tema antes de usar este código.

La documentación de Swift dice que es posible agregar inicializadores en una extensión, y el ejemplo en el documento es acerca de agregar un inicializador a una estructura . Xcode no reconoce el inicializador designado de UIColor en mi inicializador de conveniencia:

extension UIColor { convenience init(rawValue red: CGFloat, green g: CGFloat, blue b: CGFloat, alpha a: CGFloat) { // Can not find out the designated initializer here self.init() } }

¿Alguna solución?


Cambiar los tipos de parámetros también funcionará.

extension UIColor { convenience init(red: Int, green: Int, blue: Int, alpha: CGFloat) { let normalizedRed = CGFloat(red) / 255 let normalizedGreen = CGFloat(green) / 255 let normalizedBlue = CGFloat(blue) / 255 self.init(red: normalizedRed, green: normalizedGreen, blue: normalizedBlue, alpha: alpha) } }

Uso

let newColor: UIColor = UIColor.init(red: 74, green: 74, blue: 74, alpha: 1)

Por lo general, olvidaría el trabajo redundante de dividir los valores de los componentes por 255. Así que hice este método para facilitarme.


No puede hacerlo de esta manera, debe elegir diferentes nombres de parámetros para crear sus propios inicializadores de la siguiente manera:

extension UIColor { convenience init(r: UInt8, g: UInt8 , b: UInt8 , a: UInt8) { self.init(red: CGFloat(r)/255, green: CGFloat(g)/255, blue: CGFloat(b)/255, alpha: CGFloat(a)/255) } convenience init(r: Double, g: Double , b: Double , alpha: Double) { self.init(red: CGFloat(r), green: CGFloat(g), blue: CGFloat(b), alpha: CGFloat(alpha)) } } let myGreenColor1 = UIColor(r: 0, g: 255, b: 0, a: 255) let myGreenColor2 = UIColor(r: 0, g: 1, b: 0, alpha: 1)