color objective-c ios core-graphics gradient uicolor

objective c - Obtenga un color ligeramente más claro y más oscuro de UIColor



ios swift gradient (16)

TL; DR:

Rápido:

extension UIColor { var lighterColor: UIColor { return lighterColor(removeSaturation: 0.5, resultAlpha: -1) } func lighterColor(removeSaturation val: CGFloat, resultAlpha alpha: CGFloat) -> UIColor { var h: CGFloat = 0, s: CGFloat = 0 var b: CGFloat = 0, a: CGFloat = 0 guard getHue(&h, saturation: &s, brightness: &b, alpha: &a) else {return self} return UIColor(hue: h, saturation: max(s - val, 0.0), brightness: b, alpha: alpha == -1 ? a : alpha) } }

Uso:

let lightColor = somethingDark.lighterColor

C objetivo:

- (UIColor *)lighterColorRemoveSaturation:(CGFloat)removeS resultAlpha:(CGFloat)alpha { CGFloat h,s,b,a; if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) { return [UIColor colorWithHue:h saturation:MAX(s - removeS, 0.0) brightness:b alpha:alpha == -1? a:alpha]; } return nil; } - (UIColor *)lighterColor { return [self lighterColorRemoveSaturation:0.5 resultAlpha:-1]; }

@rchampourlier tenía razón en su comentario a @ user529758 (La respuesta aceptada): las soluciones HSB (o HSV) y RGB ofrecen resultados completamente diferentes. RGB simplemente agrega (o hace que el color sea más parecido a) blanco, y la solución HSB acerca el color al borde en la escala Brigtness, que básicamente comienza con negro y termina con el color puro ...

Básicamente Brillo (Valor) hace que el color se acerque menos o más al negro, donde la Saturación lo hace menos o más parecido al blanco ...

Como se ve aquí:

Por lo tanto, la solución para hacer un color realmente más brillante (es decir, más cerca del blanco ...) será hacer que su valor de Saturación sea más pequeño , dando como resultado esta solución:

- (UIColor *)lighterColor { CGFloat h,s,b,a; if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) { return [UIColor colorWithHue:h saturation:MAX(s - 0.3, 0.0) brightness:b /*MIN(b * 1.3, 1.0)*/ alpha:a]; } return nil; }

Estaba buscando poder convertir cualquier UIColor en un degradado. La forma en que intento hacer esto es mediante el uso de Core Graphics para dibujar un degradado. Lo que intento hacer es obtener un color, digamos:

[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];

y obtén un UIColor que es un poco más oscuro y un poco más claro. ¿Alguien sabe como hacer esto? Gracias.


Aquí hay una categoría de UIColor que también permite controlar la cantidad de cambio de color.

- (UIColor *)lighterColorWithDelta:(CGFloat)delta { CGFloat r, g, b, a; if ([self getRed:&r green:&g blue:&b alpha:&a]) return [UIColor colorWithRed:MIN(r + delta, 1.0) green:MIN(g + delta, 1.0) blue:MIN(b + delta, 1.0) alpha:a]; return nil; } - (UIColor *)darkerColorWithDelta:(CGFloat)delta { CGFloat r, g, b, a; if ([self getRed:&r green:&g blue:&b alpha:&a]) return [UIColor colorWithRed:MAX(r - delta, 0.0) green:MAX(g - delta, 0.0) blue:MAX(b - delta, 0.0) alpha:a]; return nil; }


Extensión universal Swift para iOS y OS X , usando getHue :

#if os(OSX) import Cocoa public typealias PXColor = NSColor #else import UIKit public typealias PXColor = UIColor #endif extension PXColor { func lighter(amount : CGFloat = 0.25) -> PXColor { return hueColorWithBrightnessAmount(1 + amount) } func darker(amount : CGFloat = 0.25) -> PXColor { return hueColorWithBrightnessAmount(1 - amount) } private func hueColorWithBrightnessAmount(amount: CGFloat) -> PXColor { var hue : CGFloat = 0 var saturation : CGFloat = 0 var brightness : CGFloat = 0 var alpha : CGFloat = 0 #if os(iOS) if getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) { return PXColor( hue: hue, saturation: saturation, brightness: brightness * amount, alpha: alpha ) } else { return self } #else getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) return PXColor( hue: hue, saturation: saturation, brightness: brightness * amount, alpha: alpha ) #endif } }

Uso:

let color = UIColor(red: 0.5, green: 0.8, blue: 0.8, alpha: 1.0) color.lighter(amount:0.5) color.darker(amount:0.5)

O (con los valores predeterminados):

color.lighter() color.darker()

Muestra:


Lo ideal es que las funciones se encapsulen dentro de una extensión de UIColor llamada UIColor+Brightness.swift y que tengan un brillo configurable; vea el ejemplo a continuación:

import UIKit extension UIColor { func lighterColorWithBrightnessFactor(brightnessFactor:CGFloat) -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if self.getRed(&r, green:&g, blue:&b, alpha:&a) { return UIColor(red:min(r + brightnessFactor, 1.0), green:min(g + brightnessFactor, 1.0), blue:min(b + brightnessFactor, 1.0), alpha:a) } return UIColor() } }


Ninguna de las soluciones publicadas funcionó bastante para todos los colores y sombras, pero luego me topé con esta biblioteca que proporciona un conjunto de extensiones muy bien implementadas para UIColor.

Específicamente tiene una función de (UIColor *)lighten:(CGFloat)amount como parte de su implementación de HSL: (UIColor *)lighten:(CGFloat)amount - que funciona perfectamente.


No estoy seguro de si está buscando algún tipo de respuesta Objective-C, pero en función de cómo funcionan los colores especificados por RGBA, creo que simplemente puede escalar los valores RGB de acuerdo con un factor arbitrario para obtener un "encendedor" o sombra "más oscura". Por ejemplo, puede tener un azul:

[UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];

¿Quieres un azul más oscuro? Multiplique los valores RGB por 0.9:

[UIColor colorWithRed:0.0 green:0.0 blue:0.9 alpha:1.0];

Voila. O tal vez tienes una naranja:

[UIColor colorWithRed:1.0 green:0.4 blue:0.0 alpha:1.0];

Elija otro factor de escala, digamos, 0.8:

[UIColor colorWithRed:0.8 green:0.32 blue:0.0 alpha:1.0];

¿Es ese el tipo de efecto que estás buscando?


Represento celdas de colores en función de un valor de estado:

Para esto escribí una extensión rápida basada en algún viejo código objc después de obtener un error usando la sugerencia de CryingHippo:

extension UIColor{ func darker(darker: CGFloat) -> UIColor{ var red: CGFloat = 0.0 var green: CGFloat = 0.0 var blue: CGFloat = 0.0 if self.colorSpace == UIColorSpace.genericGrayColorSpace(){ red = whiteComponent - darker green = whiteComponent - darker blue = whiteComponent - darker } else { red = redComponent - darker green = greenComponent - darker blue = blueComponent - darker } if red < 0{ green += red/2 blue += red/2 } if green < 0{ red += green/2 blue += green/2 } if blue < 0{ green += blue/2 red += blue/2 } return UIColor( calibratedRed: red, green: green, blue: blue, alpha: alphaComponent ) } func lighter(lighter: CGFloat) -> UIColor{ return darker(-lighter) } }

Lo mismo funciona para NSColor también. Simplemente reemplace UIColor con NSColor .


Si convierte el color RGB al modelo de color HSL , puede variar la componente L = luminosidad de L = 0.0 (negro) sobre L = 0.5 (color natural) a L = 1.0 (blanco). UIColor no puede manejar HSL directamente, pero hay una fórmula para convertir RGB <-> HSL.


Si desea que la solución de user529758 funcione con tonos de gris (como [UIColor lightGrayColor] o [UIColor darkGrayColor] debe mejorarla así:

- (UIColor *)lighterColor { CGFloat h, s, b, a; if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) { return [UIColor colorWithHue:h saturation:s brightness:MIN(b * 1.3, 1.0) alpha:a]; } CGFloat white, alpha; if ([self getWhite:&white alpha:&alpha]) { white = MIN(1.3*white, 1.0); return [UIColor colorWithWhite:white alpha:alpha]; } return nil; }

getHue:saturation:brightness:alpha falla (y devuelve false ) cuando se llama en un tono gris, por lo tanto, tendrá que usar getWhite:alpha .


Solo quería dar el mismo resultado, en RGB, que

  • colocando el color con un alfa x% sobre un fondo blanco para aclarar
  • colocando el color con un alfa x% sobre un fondo negro para oscurecer

Lo que da el mismo resultado, AFAIK, que elegir el color en un gradiente ''color a blanco'' o ''color a negro'', en x% del tamaño del degradado.

Para ese propósito, las matemáticas son simples:

// UIColor+Mix.swift import UIKit extension UIColor { func mixLighter (amount: CGFloat = 0.25) -> UIColor { return mixWithColor(UIColor.whiteColor(), amount:amount) } func mixDarker (amount: CGFloat = 0.25) -> UIColor { return mixWithColor(UIColor.blackColor(), amount:amount) } func mixWithColor(color: UIColor, amount: CGFloat = 0.25) -> UIColor { var r1 : CGFloat = 0 var g1 : CGFloat = 0 var b1 : CGFloat = 0 var alpha1 : CGFloat = 0 var r2 : CGFloat = 0 var g2 : CGFloat = 0 var b2 : CGFloat = 0 var alpha2 : CGFloat = 0 self.getRed (&r1, green: &g1, blue: &b1, alpha: &alpha1) color.getRed(&r2, green: &g2, blue: &b2, alpha: &alpha2) return UIColor( red:r1*(1.0-amount)+r2*amount, green:g1*(1.0-amount)+g2*amount, blue:b1*(1.0-amount)+b2*amount, alpha: alpha1 ) } }

Aquí hay ejemplos con algunos colores


Todas las otras respuestas en este hilo usan el sistema de color RGB o simplemente cambian el valor de matiz o brillo del sistema HSB . Como se explica en detalle en esta gran publicación de blog, la forma correcta de hacer que un color sea más claro o más oscuro es cambiar su valor de luminance . Ninguna de las otras respuestas hace eso. Si quieres hacerlo bien, utiliza mi solución o escribe la tuya después de leer la publicación del blog.

Desafortunadamente es bastante complicado cambiar cualquiera de los atributos de un UIColor de forma predeterminada . Además, Apple ni siquiera admite ningún espacio de color basado en LAB como HCL en la clase UIColor (el L en LAB es el valor de luminance que estamos buscando).

Usar HandyUIKit (instalarlo a través de Carthage) agrega soporte para HCL y hace su vida mucho más fácil :

import HandyUIKit let color = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0) // create a new UIColor object with a specific luminance (slightly lighter) color.change(.luminance, to: 0.7)

También hay una opción para aplicar un cambio relativo (recomendado):

// create a new UIColor object with slightly darker color color.change(.luminance, by: -0.2)

Tenga en cuenta que HandyUIKit también agrega algunas otras características prácticas de la interfaz de usuario en su proyecto; revise su HandyUIKit para obtener más detalles.

¡Espero que ayude!


UIColor extensión y fijación más claroColorForColor

extension UIColor { class func darkerColorForColor(color: UIColor) -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if color.getRed(&r, green: &g, blue: &b, alpha: &a){ return UIColor(red: max(r - 0.2, 0.0), green: max(g - 0.2, 0.0), blue: max(b - 0.2, 0.0), alpha: a) } return UIColor() } class func lighterColorForColor(color: UIColor) -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if color.getRed(&r, green: &g, blue: &b, alpha: &a){ let tmpColor = UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a) println(tmpColor) return tmpColor } return UIColor() } }


La solución de user529758 en Swift:

Color más oscuro:

func darkerColorForColor(color: UIColor) -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if color.getRed(&r, green: &g, blue: &b, alpha: &a){ return UIColor(red: max(r - 0.2, 0.0), green: max(g - 0.2, 0.0), blue: max(b - 0.2, 0.0), alpha: a) } return UIColor() }

Color más claro:

func lighterColorForColor(color: UIColor) -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if color.getRed(&r, green: &g, blue: &b, alpha: &a){ return UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a) } return UIColor() }


Sebyddd solución como una extensión:

extension UIColor { func darker() -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if self.getRed(&r, green: &g, blue: &b, alpha: &a){ return UIColor(red: max(r - 0.2, 0.0), green: max(g - 0.2, 0.0), blue: max(b - 0.2, 0.0), alpha: a) } return UIColor() } func lighter() -> UIColor { var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if self.getRed(&r, green: &g, blue: &b, alpha: &a){ return UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a) } return UIColor() } }

Uso:

let darkerYellow = UIColor.yellow.darker() let lighterYellow = UIColor.yellow.lighter()


Una extensión de Swift basada en la respuesta de @Sebyddd:

import Foundation import UIKit extension UIColor{ func colorWith(brightness: CGFloat) -> UIColor{ var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0 if getRed(&r, green: &g, blue: &b, alpha: &a){ return UIColor(red: max(r + brightness, 0.0), green: max(g + brightness, 0.0), blue: max(b + brightness, 0.0), alpha: a) } return UIColor() } }


- (UIColor *)lighterColorForColor:(UIColor *)c { CGFloat r, g, b, a; if ([c getRed:&r green:&g blue:&b alpha:&a]) return [UIColor colorWithRed:MIN(r + 0.2, 1.0) green:MIN(g + 0.2, 1.0) blue:MIN(b + 0.2, 1.0) alpha:a]; return nil; } - (UIColor *)darkerColorForColor:(UIColor *)c { CGFloat r, g, b, a; if ([c getRed:&r green:&g blue:&b alpha:&a]) return [UIColor colorWithRed:MAX(r - 0.2, 0.0) green:MAX(g - 0.2, 0.0) blue:MAX(b - 0.2, 0.0) alpha:a]; return nil; }

Úselo así:

UIColor *baseColor = // however you obtain your color UIColor *lighterColor = [self lighterColorForColor:baseColor]; UIColor *darkerColor = [self darkerColorForColor:baseColor];

EDITAR : como @Anchu Chimala señaló, para una flexibilidad máxima, estos métodos deberían implementarse como una categoría UIColor. Además, a partir de la idea de @Riley, puede ser una mejor idea hacer el color más oscuro o más claro en lugar de sumar o restar valores constantes. Como señaló @jrturton, no es necesario manipular los componentes RGB; es mejor modificar la propiedad de brillo en sí. Considerándolo todo:

@implementation UIColor (LightAndDark) - (UIColor *)lighterColor { CGFloat h, s, b, a; if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) return [UIColor colorWithHue:h saturation:s brightness:MIN(b * 1.3, 1.0) alpha:a]; return nil; } - (UIColor *)darkerColor { CGFloat h, s, b, a; if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) return [UIColor colorWithHue:h saturation:s brightness:b * 0.75 alpha:a]; return nil; } @end