Swift 3 将 2 种颜色放在同一个 UIView 中

Posted

技术标签:

【中文标题】Swift 3 将 2 种颜色放在同一个 UIView 中【英文标题】:Swift 3 put 2 colors in the same UIView 【发布时间】:2017-10-06 06:46:09 【问题描述】:

我想在 UIViews 和 UIImageViews 上实现这个效果:

在 UIView 上,我知道我可以在其中放入 2 个不同颜色的,但我认为一定有更好的方法,但我不知道如何在 UIImageVIew 中做到这一点。某种 pod 会非常有用,因为我找不到。

【问题讨论】:

你应该使用两种颜色的图像。它比尝试在图像视图中放置两种颜色更相关。为什么要放两种颜色?改用图片! 在这里请求教程或库不是一个有效的话题。 问题是当它“未激活”时我需要将其设为灰色,并且我无法在其上应用正常色调,因为灰色将有 2 种颜色 @ElTomato 代码在这里完全可以,我只是说我更喜欢 pod,因为它使事情变得更容易。如果您有有效的方法,我将不胜感激。 【参考方案1】:

您可以添加一个渐变层,而不是从一种颜色过渡到另一种颜色,而是从一种颜色变为相同颜色直到中间点,下半部分也是如此。检查示例:

let twoColorView = UIView(frame: CGRect(x: 40, y: 100, width: 200, height: 100))
let gradientLayer = CAGradientLayer()
gradientLayer.frame = twoColorView.bounds
gradientLayer.colors = [UIColor.red.cgColor, UIColor.red.cgColor, UIColor.blue.cgColor, UIColor.blue.cgColor]
gradientLayer.locations = [NSNumber(value: 0.0), NSNumber(value: 0.5), NSNumber(value: 0.5), NSNumber(value: 1.0)]
twoColorView.layer.addSublayer(gradientLayer)

当然,您可以进一步设置该视图的样式,例如:

twoColorView.layer.cornerRadius = twoColorView.bounds.height / 2
twoColorView.layer.masksToBounds = true

结果如下:

编辑

它可以泛化为接受任意数量的颜色。创建一个UIView 扩展并在那里添加你的逻辑。这样颜色就可以应用于任何UIView及其子类,如UILabel、UIButton、UIImageView等。

extension UIView 
    func addColors(colors: [UIColor]) 
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.bounds

        var colorsArray: [CGColor] = []
        var locationsArray: [NSNumber] = []
        for (index, color) in colors.enumerated() 
            // append same color twice
            colorsArray.append(color.cgColor)
            colorsArray.append(color.cgColor)
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index)))
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index + 1)))
        

        gradientLayer.colors = colorsArray
        gradientLayer.locations = locationsArray

        self.backgroundColor = .clear
        self.layer.addSublayer(gradientLayer)

        // This can be done outside of this funciton
        self.layer.cornerRadius = self.bounds.height / 2
        self.layer.masksToBounds = true
    

并添加颜色:

    let colorView = UIImageView(frame: CGRect(x: 40, y: 100, width: 200, height: 100))
    colorView.addColors(colors: [.red, .green, .blue])
    view.addSubview(colorView)

这是结果:

注意不要在视图的生命周期中多次调用这个函数,因为它会在彼此之上添加子层。因此,要么调用一次,要么在再次调用addColors 之前删除子层。所以当然还有改进的余地。

【讨论】:

如果您指定您的问题,也许有人会帮助您。 UITableViewCell 很大程度上取决于UITableView 的显示方式——您需要考虑单元格的重用、时间安排(例如,尝试在willDisplayCell 中设置)和单元格的子视图(contentView)。但如果没有进一步的信息,我无法判断你出了什么问题。【参考方案2】:

Swift 4 中更加静态和客观的方式,

class ColouredView: UIView 
    override class var layerClass : AnyClass 
        return ColouredLayer.self
    



class ColouredLayer: CAGradientLayer

    override init() 
        super.init()

        let colors = [UIColor.red, UIColor.blue]
        addColors(colors)
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    





extension CAGradientLayer

    func addColors(_ colors: [UIColor])
        var colorsArray: [CGColor] = []
        var locationsArray: [NSNumber] = []
        for (index, color) in colors.enumerated() 
            // append same color twice
            colorsArray.append(color.cgColor)
            colorsArray.append(color.cgColor)
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index)))
            locationsArray.append(NSNumber(value: (1.0 / Double(colors.count)) * Double(index + 1)))
        

        self.colors = colorsArray
        locations = locationsArray
    

只需设置和分配ColouredView

感谢@Au Ris 的回答

【讨论】:

【参考方案3】:

通过方向改进上述答案

extension UIView 

enum GradientDirection 
    case horizontal
    case vertical


func fillColors(_ colors: [UIColor], withPercentage percentages: [Double], direction: GradientDirection = .horizontal) 
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = bounds
    var colorsArray: [CGColor] = []
    var locationsArray: [NSNumber] = []
    var total = 0.0
    locationsArray.append(0.0)
    for (index, color) in colors.enumerated() 
        // append same color twice
        colorsArray.append(color.cgColor)
        colorsArray.append(color.cgColor)
        // Calculating locations w.r.t Percentage of each
        if index + 1 < percentages.count 
            total += percentages[index]
            let location = NSNumber(value: total / 100)
            locationsArray.append(location)
            locationsArray.append(location)
        
    
    locationsArray.append(1.0)
    if direction == .horizontal 
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
     else 
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
        gradientLayer.endPoint = CGPoint(x: 0.0, y: 1.0)
    
    gradientLayer.colors = colorsArray
    gradientLayer.locations = locationsArray
    backgroundColor = .clear
    layer.addSublayer(gradientLayer)

    

【讨论】:

【参考方案4】:

它可以更概括地接受任意数量的颜色,以及它们各自的百分比

extension UIView 
    func addColors(colors: [UIColor], withPercentage percentages: [Double]) 
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = self.bounds
        var colorsArray: [CGColor] = []
        var locationsArray: [NSNumber] = []
        var total = 0.0
        locationsArray.append(0.0)
        for (index, color) in colors.enumerated() 
            // append same color twice
            colorsArray.append(color.cgColor)
            colorsArray.append(color.cgColor)
            // Calculating locations w.r.t Percentage of each
            if index+1 < percentages.count
                total += percentages[index]
                let location: NSNumber = NSNumber(value: total/100)
                locationsArray.append(location)
                locationsArray.append(location)
            
        
        locationsArray.append(1.0)
        gradientLayer.colors = colorsArray
        gradientLayer.locations = locationsArray
        self.backgroundColor = .clear
        self.layer.addSublayer(gradientLayer)
    

用法:

let colors: [UIColor] = [.red, .green, .blue, .yellow, .purple]
let percentages: [Double] = [10, 30, 20, 5, 35]
testView.addColors(colors: colors, withPercentage: percentages)

结果:

感谢@Au Ris 的回答

【讨论】:

嗨,我有一个简短的问题。我可以在填充颜色时添加动画吗?它为 UIView 设置动画并将颜色填充。谢谢!

以上是关于Swift 3 将 2 种颜色放在同一个 UIView 中的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 3 中更改 tableView 中的图像颜色

在swift 2中改变球类型的颜色

Swift iOS Sprite Kit - 将精灵从一种颜色淡化为另一种颜色[关闭]

如何使用 userDefaults 保存打印数组(swift 3)

swift 3 layoutIfneeded 无法正常工作

使用 Swift 添加贴纸背景颜色