我想应用视图渐变颜色但总是失败。
我想应用像这样的图像的渐变视图:
我尝试使用这段代码:
func gradientColor(topLeft: UIColor, bottomRight: UIColor) {
let gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: self.mainView.bounds.width, height: self.mainView.bounds.height)
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
gradient.colors = [topLeft.cgColor, bottomRight.cgColor]
self.mainView.layer.addSublayer(gradient)
}
但是如果我这样调用,结果是空的,没有颜色(颜色没有显示):
gradientColor(topLeft: UIColor.style.negativeGradient, bottomRight: UIColor.style.negative)
生成像该图像一样的渐变视图的正确代码是什么?
这种方法通常会失败,因为它被称为 before 视图已经布局,因此
self.mainView.bounds
无效。
一种更可靠且灵活的方法是对
UIView
进行子类化并让它自动完成所有“背景样式”。
快速示例课程:
class MyCustomGradientView: UIView {
public var gradientColor1: UIColor = .init(red: 0.887, green: 0.993, blue: 0.922, alpha: 1.0) { didSet { gradientLayer.colors = [gradientColor1.cgColor, gradientColor2.cgColor] } }
public var gradientColor2: UIColor = .white { didSet { gradientLayer.colors = [gradientColor1.cgColor, gradientColor2.cgColor] } }
public var circleColor: UIColor = .init(red: 0.904, green: 0.969, blue: 0.949, alpha: 1.0) { didSet { circleLayer.fillColor = circleColor.cgColor } }
public var circleDiameter: CGFloat = 140.0 { didSet { setNeedsLayout() } }
public var circleOffset: CGPoint = .init(x: -28.0, y: -2.0) { didSet { setNeedsLayout() } }
override class var layerClass: AnyClass { CAGradientLayer.self }
private var gradientLayer: CAGradientLayer { layer as! CAGradientLayer }
private let circleLayer: CAShapeLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
private func commonInit() {
self.backgroundColor = .clear
gradientLayer.colors = [gradientColor1.cgColor, gradientColor2.cgColor]
gradientLayer.startPoint = .init(x: 0.0, y: 0.0)
gradientLayer.endPoint = .init(x: 1.0, y: 1.0)
circleLayer.fillColor = circleColor.cgColor
layer.addSublayer(circleLayer)
layer.cornerRadius = 16.0
layer.masksToBounds = true
}
override func layoutSubviews() {
super.layoutSubviews()
// position the circle so its center is at bottom-right corner
// offset circleOffset
let r: CGRect = .init(x: bounds.maxX - circleDiameter * 0.5, y: bounds.maxY - circleDiameter * 0.5, width: circleDiameter, height: circleDiameter)
.offsetBy(dx: circleOffset.x, dy: circleOffset.y)
circleLayer.path = UIBezierPath(ovalIn: r).cgPath
}
}
你可能正在这样做:
mainView = UIView()
// set constraints on mainView
所以,我们可以这样做:
mainView = MyCustomGradientView()
// set constraints on mainView
我们得到这个(例如):
我们可以添加多个不同大小的实例:
我们可以像平常一样添加子视图:
并根据需要设置/更改颜色: