我想在UIViews和UIImageViews上实现这个效果:
关于UIView我知道我可以用不同的颜色把它放在里面,但我几乎认为必须有一个更好的方法,我不知道如何在UIImageVIew中做到这一点。某种pod非常有用,因为我无法找到它。
答案 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
结果如下:
修改强>:
可以概括为接受任意数量的颜色。创建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
之前,请先调用一次或删除子图层。所以当然还有改进的余地。
答案 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)
结果:
感谢@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)
}
}