在Swift中,如何从背景颜色确定文本颜色?

10
我正在使用Swift制作一个颜色选择器应用程序,需要使文本适应背景颜色。
默认情况下,我的UIView上的文本是黑色的,如果有较暗的背景颜色,则希望文本变得更浅,如果有较亮的背景颜色,则希望文本变得更暗,以使文本更易读。
以下是一些截图:
几乎无法阅读的文本(第一张图片) img 几乎无法阅读的文本(第二张图片) img 如有可能,请回复,谢谢。
3个回答

38

你可以像这样做:

extension UIColor
{
    var isDarkColor: Bool {
        var r, g, b, a: CGFloat
        (r, g, b, a) = (0, 0, 0, 0)
        self.getRed(&r, green: &g, blue: &b, alpha: &a)
        let lum = 0.2126 * r + 0.7152 * g + 0.0722 * b
        return  lum < 0.50
    }
}

这将计算颜色的亮度,并确定它是否高于某个阈值。然后说 myLabel.textColor = view.backgroundColor?.isDarkColor == true ? .white : .black


4
如果你想在UIImage上使用这个答案,你可以使用这个框架来获取图像的主要颜色。https://github.com/jathu/UIImageColors - Adrian
@Adrian,你能告诉我如何使用这个框架吗?我正在尝试在Xcode中根据背景图片视图调整文本标签的颜色。谢谢! - Pressing_Keys_24_7
1
太棒了,谢谢!我制作了一组有用的扩展来配合这个 https://gist.github.com/froggomad/cc4fa0f8e77bf548d23606bcd8290fce - froggomad
1
实际上,这并不计算亮度。要正确计算亮度,您必须首先线性化数据。话虽如此,在问题的情况下,这已经足够好了。只是不是亮度而已。把它看作亮度代理。 - Victor Engel

2
除了@beyowulf的答案外,在SwiftUI中,您可以将转换为并应用它。
extension UIColor
{
    var isDarkColor: Bool {
        var r, g, b, a: CGFloat
        (r, g, b, a) = (0, 0, 0, 0)
        self.getRed(&r, green: &g, blue: &b, alpha: &a)
        let lum = 0.2126 * r + 0.7152 * g + 0.0722 * b
        return  lum < 0.50
    }
}

extension Color{
    var isDarkColor : Bool {
        return UIColor(self).isDarkColor
    }
}

0
如果您需要一个适用于暗黑模式和明亮模式的解决方案,请使用这个扩展。
extension UIColor {
    
    convenience init(
        light lightModeColor: @escaping @autoclosure () -> UIColor,
        dark darkModeColor: @escaping @autoclosure () -> UIColor
     ) {
        self.init { traitCollection in
            switch traitCollection.userInterfaceStyle {
            case .light:
                return lightModeColor()
            case .dark:
                return darkModeColor()
            case .unspecified:
                return lightModeColor()
            @unknown default:
                return lightModeColor()
            }
        }
    }
    
    /// returns true if is a dark color
    var isDarkColor: Bool {
        var r, g, b, a: CGFloat
        (r, g, b, a) = (0, 0, 0, 0)
        self.getRed(&r, green: &g, blue: &b, alpha: &a)
        let lum = 0.2126 * r + 0.7152 * g + 0.0722 * b
        return  lum < 0.45
    }
    
    /// Generates contrasting color for dark and light userInterfaceStyles
    /// - Returns: UIColor.white for dark colors else return UIColor.black
    func contrastingColor() -> UIColor {
        let dark = self.resolvedColor(with: UITraitCollection(userInterfaceStyle: .dark))
        let light = self.resolvedColor(with: UITraitCollection(userInterfaceStyle: .light))
        
        return UIColor(light: light.isDarkColor ? .white : .black,
                       dark: dark.isDarkColor ? .white : .black)
    }
    
}

演示:

代码参考 对比文本

let backgroundColor = UIColor.black
let contrastingColor = backgroundColor.contrastingColor()

GIF_description


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接