首页 文章

为给定的UIColor获得更浅和更暗的颜色变化

提问于
浏览
37

如何在Swift中获得给定UIColor的不同更亮和更暗的变化?

enter image description here

6 回答

  • 88

    更新

    使用以下 UIColor Extension:

    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 red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
            if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
                return UIColor(red: min(red + percentage/100, 1.0),
                               green: min(green + percentage/100, 1.0),
                               blue: min(blue + percentage/100, 1.0),
                               alpha: alpha)
            } else {
                return nil
            }
        }
    }
    

    Usage:

    let color = UIColor(red:0.96, green:0.54, blue:0.10, alpha:1.0)
    color.lighter(30) // returns lighter color by 30%
    color.darker(30) // returns darker color by 30%
    

    而不是 .lighter().darker() ,您可以使用 .adjust() ,其中正值用于闪电,负值用于变暗

    color.adjust(-30) // 30% darker color
    color.adjust(30) // 30% lighter color
    

    Output:

    enter image description here

  • 2

    我想提供另一个使用亮度和饱和度而不是RGB的版本

    extension UIColor {
      /**
       Create a ligher color
       */
      func lighter(by percentage: CGFloat = 30.0) -> UIColor {
        return self.adjustBrightness(by: abs(percentage))
      }
    
      /**
       Create a darker color
       */
      func darker(by percentage: CGFloat = 30.0) -> UIColor {
        return self.adjustBrightness(by: -abs(percentage))
      }
    
      /**
       Try to increase brightness or decrease saturation
       */
      func adjustBrightness(by percentage: CGFloat = 30.0) -> UIColor {
        var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        if self.getHue(&h, saturation: &s, brightness: &b, alpha: &a) {
          if b < 1.0 {
            let newB: CGFloat = max(min(b + (percentage/100.0)*b, 1.0), 0.0)
            return UIColor(hue: h, saturation: s, brightness: newB, alpha: a)
          } else {
            let newS: CGFloat = min(max(s - (percentage/100.0)*s, 0.0), 1.0)
            return UIColor(hue: h, saturation: newS, brightness: b, alpha: a)
          }
        }
        return self
      }
    }
    
  • 26

    Kenji-Tran的答案很好,只要您的起始颜色不是黑色(亮度值0) . 通过添加几行额外代码,您还可以使黑色“更亮”(即将其变亮为灰度或颜色值) .

    Note: 我不是't able to add this change using an Edit and I' m不允许评论Kenji-Tran 's answer due to my 3025048 rep, therefore I found no other way to share my knowledge on SO then by posting a new answer. I hope that'没关系 .

    extension UIColor {
      /**
       Create a ligher color
       */
      func lighter(by percentage: CGFloat = 30.0) -> UIColor {
        return self.adjustBrightness(by: abs(percentage))
      }
    
      /**
       Create a darker color
       */
      func darker(by percentage: CGFloat = 30.0) -> UIColor {
        return self.adjustBrightness(by: -abs(percentage))
      }
    
      /**
       Try to increase brightness or decrease saturation
       */
      func adjustBrightness(by percentage: CGFloat = 30.0) -> UIColor {
        var h: CGFloat = 0, s: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        if self.getHue(&h, saturation: &s, brightness: &b, alpha: &a) {
          if b < 1.0 {
            /**
             Below is the new part, which makes the code work with black as well as colors
            */
            let newB: CGFloat
            if b == 0.0 {
                newB = max(min(b + percentage/100, 1.0), 0.0)
            } else {
                newB = max(min(b + (percentage/100.0)*b, 1.0), 0,0)
            }
            return UIColor(hue: h, saturation: s, brightness: newB, alpha: a)
          } else {
            let newS: CGFloat = min(max(s - (percentage/100.0)*s, 0.0), 1.0)
            return UIColor(hue: h, saturation: newS, brightness: b, alpha: a)
          }
        }
        return self
      }
    }
    
  • 2

    Version with RGB values modification

    这里我把简单的 UIColor 扩展名基于之前的答案 . 它对我来说非常合适 .

    下面演示:

    Colors demo

    Colors manipulation code

    public extension UIColor {
    
        /**
         Create a lighter color
         */
        public func lighter(by percentage: CGFloat = 30.0) -> UIColor {
            return self.adjustBrightness(by: abs(percentage))
        }
    
        /**
         Create a darker color
         */
        public func darker(by percentage: CGFloat = 30.0) -> UIColor {
            return self.adjustBrightness(by: -abs(percentage))
        }
    
        /**
         Changing R, G, B values
         */
    
        func adjustBrightness(by percentage: CGFloat = 30.0) -> UIColor {
    
            var red: CGFloat = 0.0
            var green: CGFloat = 0.0
            var blue: CGFloat = 0.0
            var alpha: CGFloat = 0.0
    
            if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
    
                let pFactor = (100.0 + percentage) / 100.0
    
                let newRed = (red*pFactor).clamped(to: 0.0 ... 1.0)
                let newGreen = (green*pFactor).clamped(to: 0.0 ... 1.0)
                let newBlue = (blue*pFactor).clamped(to: 0.0 ... 1.0)
    
                return UIColor(red: newRed, green: newGreen, blue: newBlue, alpha: alpha)
            }
    
            return self
        }
    }
    

    Clamped function 扩展可轻松保持最小值和最大值之间的值 .

    extension Comparable {
    
        func clamped(to range: ClosedRange<Self>) -> Self {
    
            if self > range.upperBound {
                return range.upperBound
            } else if self < range.lowerBound {
                return range.lowerBound
            } else {
                return self
            }
        }
    }
    
  • 0

    Tested in Xcode 10 with Swift 4.x for iOS 12

    从你的颜色开始作为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 .

  • 0

    使用lukszar clampled函数,我使用实际比例的RGB值为UIColor扩展编写了这个函数 . 我希望它有所帮助

    public extension UIColor {
    
      public func lighter(by percentage: CGFloat = 30.0) -> UIColor {
        return self.adjustBrightness(by: abs(percentage))
      }
    
      public func darker(by percentage: CGFloat = 30.0) -> UIColor {
        return self.adjustBrightness(by: -abs(percentage))
      }
    
      func adjustBrightness(by percentage: CGFloat = 30.0) -> UIColor {
    
        let ratio = percentage/100
    
        var red:   CGFloat = 0.0
        var green: CGFloat = 0.0
        var blue:  CGFloat = 0.0
        var alpha: CGFloat = 0.0
    
        if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
          let newRed =   (red   + ((ratio < 0) ? red   * ratio : (1 - red)   * ratio)).clamped(to: 0.0 ... 1.0)
          let newGreen = (green + ((ratio < 0) ? green * ratio : (1 - green) * ratio)).clamped(to: 0.0 ... 1.0)
          let newBlue =  (blue  + ((ratio < 0) ? blue  * ratio : (1 - blue)  * ratio)).clamped(to: 0.0 ... 1.0)
          return UIColor(red: newRed, green: newGreen, blue: newBlue, alpha: alpha)
        }
        return self
      }
    }
    

相关问题