我一直希望能够将任何UIColor变成渐变。我打算这样做的方法是使用Core Graphics绘制渐变。我想做的就是获得一种颜色,让我们说:
[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
并获得一个UIColor,它的阴影要深一些,而阴影要浅一些。有谁知道如何做到这一点?谢谢。
我一直希望能够将任何UIColor变成渐变。我打算这样做的方法是使用Core Graphics绘制渐变。我想做的就是获得一种颜色,让我们说:
[UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
并获得一个UIColor,它的阴影要深一些,而阴影要浅一些。有谁知道如何做到这一点?谢谢。
Answers:
- (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;
}
像这样使用它:
UIColor *baseColor = // however you obtain your color
UIColor *lighterColor = [self lighterColorForColor:baseColor];
UIColor *darkerColor = [self darkerColorForColor:baseColor];
编辑:正如@Anchu Chimala指出的那样,为了获得最大的灵活性,应该将这些方法实现为UIColor类别。同样,从@Riley的想法出发,最好将颜色按比例变暗或变亮,而不是增加或减去恒定值。正如@jrturton所指出的,没有必要操纵RGB组件。最好修改亮度属性本身。总而言之:
@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
getHue:saturation:brightness
有UIKit 的签名,但似乎它可以与HSV而不是HSB一起使用。在这种情况下更改亮度(实际上是该值)将不起作用。例如,纯红色(rgb(255,0,0))的亮度/值为1,因此无法通过该亮度进行照明。我最终改为使用RGB值进行更改。
getHue:saturation:brightness:alpha
将返回FALSE。
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)
}
}
用法:
let lightColor = somethingDark.lighterColor
- (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对@ user529758(已接受的答案)的评论是正确的-HSB(或HSV)和RGB解决方案给出的结果完全不同。RGB只是添加(或使颜色更接近)白色,而HSB解决方案使颜色更接近Brigtness比例尺的边缘-基本上从黑色开始,以纯色结束...
基本上,“亮度(值)”使颜色越来越接近黑色,而“饱和度”使颜色越来越接近白色...
如此处所示:
因此,使颜色实际上更亮(即更接近白色...)的解决方案将是使其饱和度值更小,从而得出以下解决方案:
- (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;
}
适用于iOS和OS X的Swift通用扩展,使用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
}
}
用法:
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)
或(使用默认值):
color.lighter()
color.darker()
样品:
let color = usingColorSpaceName(NSCalibratedRGBColorSpace)
,然后将getHue
调用替换为对颜色的调用:color?.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
_
在单词数量前缺少a 。应该是private func hueColorWithBrightnessAmount(_ amount: CGFloat) -> PXColor {
我只是想在RGB中给出相同的结果
与以渐变大小的x%从“从颜色到白色”或“从颜色到黑色”的渐变中选择颜色相比,这提供了相同的结果AFAIK。
为此,数学很简单:
extension UIColor {
func mix(with color: UIColor, amount: CGFloat) -> UIColor {
var red1: CGFloat = 0
var green1: CGFloat = 0
var blue1: CGFloat = 0
var alpha1: CGFloat = 0
var red2: CGFloat = 0
var green2: CGFloat = 0
var blue2: CGFloat = 0
var alpha2: CGFloat = 0
getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1)
color.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2)
return UIColor(
red: red1 * (1.0 - amount) + red2 * amount,
green: green1 * (1.0 - amount) + green2 * amount,
blue: blue1 * (1.0 - amount) + blue2 * amount,
alpha: alpha1
)
}
}
这是一些颜色的例子
Swift中user529758的解决方案:
深色:
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()
}
较浅的颜色:
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()
}
var darker: UIColor
。
Sebyddd
解决方案作为扩展:
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()
}
}
用法:
let darkerYellow = UIColor.yellow.darker()
let lighterYellow = UIColor.yellow.lighter()
如果您希望user529758的解决方案使用灰色阴影(例如,[UIColor lightGrayColor]
或者[UIColor darkGrayColor]
您必须像这样进行改进:
- (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
false
在灰色阴影上调用时失败(并返回),因此您需要使用getWhite:alpha
。
UIColor扩展和更正lighterColorForColor
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()
}
}
该线程中的所有其他答案都使用RGB颜色系统,或仅更改HSB系统的色相或亮度值。正如在这篇很棒的博客文章中详细解释的那样,使颜色变浅或变深的正确方法是更改其luminance
值。其他答案都没有做到这一点。如果您想做正确的事,请使用我的解决方案或在阅读博客文章后自行编写。
不幸的是,默认情况下更改UIColor 的任何属性都是很麻烦的。此外,Apple甚至不支持此类中的任何基于LAB的色彩空间(例如HCL)(在LAB中是我们正在寻找的值)。UIColor
L
luminance
使用HandyUIKit(通过Carthage安装)可以增加对HCL的支持,并使您的生活变得更加轻松:
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)
还有一个选项可以应用相对更改(推荐):
// create a new UIColor object with slightly darker color
color.change(.luminance, by: -0.2)
请注意,HandyUIKit还向您的项目中添加了一些其他方便的UI功能 – 在GitHub上查看其README了解更多详细信息。
希望对您有所帮助!
我不确定您是否要寻找某种Objective-C的答案,但是根据RGBA指定的颜色如何工作,我认为您可以根据任意因素简单地缩放RGB值,以获得“更亮”或“较暗”的阴影。例如,您可能有一个蓝色:
[UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];
想要深蓝色吗?RGB值乘以0.9:
[UIColor colorWithRed:0.0 green:0.0 blue:0.9 alpha:1.0];
瞧 或者,也许您有一个橘子:
[UIColor colorWithRed:1.0 green:0.4 blue:0.0 alpha:1.0];
选择另一个比例因子,例如0.8:
[UIColor colorWithRed:0.8 green:0.32 blue:0.0 alpha:1.0];
您正在寻找那种效果吗?
在iOS 12的Swift 4.x中通过Xcode 10测试
从您的颜色作为UIColor开始,然后选择一个变暗的因子(作为CGFloat)
let baseColor = UIColor.red
let darkenFactor: CGFloat = 2
CGColor类型具有一个可选值components
,该值将颜色分解为RGBA(作为CGFloat数组,其值在0到1之间)。然后,您可以使用从CGColor中获取的RGBA值来重建UIColor并对其进行操作。
let darkenedBase = UIColor(displayP3Red: startColor.cgColor.components![0] / darkenFactor, green: startColor.cgColor.components![1] / darkenFactor, blue: startColor.cgColor.components![2] / darkenFactor, alpha: 1)
在此示例中,每个RGB值均被2除以使颜色变暗为以前的一半。Alpha值保持不变,但是您也可以在Alpha值而不是RGB上应用变暗因子。
斯威夫特5
extension UIColor {
func lighter(by percentage:CGFloat=30.0) -> UIColor? {
return self.adjust(by: abs(percentage) )
}
func darker(by percentage:CGFloat=30.0) -> UIColor? {
return self.adjust(by: -1 * abs(percentage) )
}
func adjust(by percentage:CGFloat=30.0) -> 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 + percentage/100, 1.0),
green: min(g + percentage/100, 1.0),
blue: min(b + percentage/100, 1.0),
alpha: a)
}else{
return nil
}
}
}
理想情况下,这些函数应该封装在UIColor
名为的扩展内UIColor+Brightness.swift
,并具有可配置的亮度-请参见以下示例:
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()
}
}
我根据状态值渲染彩色单元格:
为此,在使用CryingHippo的建议出错时,我基于一些旧的objc代码编写了一个快速扩展:
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)
}
}
同样也适用NSColor
。只需替换UIColor
为NSColor
。
这是一个UIColor类别,它也允许控制颜色变化的数量。
- (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;
}
基于@Sebyddd答案的Swift扩展:
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()
}
}