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

时间:2017-10-06 06:46:09

标签: ios swift uiview uiimageview

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

UIImageView

UIView

关于UIView我知道我可以用不同的颜色把它放在里面,但我几乎认为必须有一个更好的方法,我不知道如何在UIImageVIew中做到这一点。某种pod非常有用,因为我无法找到它。

4 个答案:

答案 0 :(得分:5)

您可以添加渐变图层,而不是从一种颜色转换到另一种颜色,而是从颜色到相同颜色直到中间点,并且与后半部分相同。检查示例:

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

结果如下:

enter image description here

修改

可以概括为接受任意数量的颜色。创建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)

结果如下:

enter image description here

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

答案 1 :(得分:1)

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的回答

答案 2 :(得分:0)

可以更广泛地接受任意数量的颜色及其各自的百分比

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)

结果:

enter image description here

感谢@Au Ris的回答

答案 3 :(得分:0)

根据指导改善以上答案

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)
}
    }