iOS中drawLinearGradient绘制对角线渐变在视图宽>高时异常的修复方法
修复对角线渐变覆盖异常的问题
问题根源在于你设置的渐变起点和终点是矩形的对角,但线性渐变的色彩插值仅沿这条直线进行,当矩形宽高不等时,这条直线的渐变范围无法覆盖整个矩形的四个角,导致宽大于高的矩形出现右上角无红色、左下角无绿色的异常。
修复方案1:调整渐变起点终点覆盖全矩形
通过计算矩形的外接延伸范围,让渐变直线的延长线覆盖整个目标矩形,确保四个角都能获取到对应端点的颜色。修改后的代码如下:
import UIKit class GradientView: UIView { override func draw(_ rect: CGRect) { let context = UIGraphicsGetCurrentContext()! context.saveGState() context.clip(to: rect) let topColor = UIColor.red let bottomColor = UIColor.green var tr = CGFloat(0), tg = CGFloat(0), tb = CGFloat(0), ta = CGFloat(0) var br = CGFloat(0), bg = CGFloat(0), bb = CGFloat(0), ba = CGFloat(0) topColor.getRed(&tr, green: &tg, blue: &tb, alpha: &ta) bottomColor.getRed(&br, green: &bg, blue: &bb, alpha: &ba) let gradient = CGGradient(colorSpace: CGColorSpaceCreateDeviceRGB(), colorComponents: [tr,tg,tb,ta,br,bg,bb,ba], locations: [0.0, 1.0], count: 2) // 计算能覆盖整个矩形的渐变起点和终点 let width = rect.size.width let height = rect.size.height let diagonalLength = sqrt(width * width + height * height) let angle = atan2(height, width) // 向对角线两端延伸,确保渐变覆盖整个矩形 let startX = rect.midX - diagonalLength * cos(angle) let startY = rect.midY - diagonalLength * sin(angle) let endX = rect.midX + diagonalLength * cos(angle) let endY = rect.midY + diagonalLength * sin(angle) context.drawLinearGradient(gradient!, start: CGPoint(x: startX, y: startY), end: CGPoint(x: endX, y: endY), options: []) context.restoreGState() } }
修复方案2:使用CAGradientLayer(更推荐)
iOS中实现渐变视图更简洁高效的方式是用CAGradientLayer,无需手动实现draw(_:),自动适配所有宽高比:
import UIKit class GradientView: UIView { override class var layerClass: AnyClass { return CAGradientLayer.self } override init(frame: CGRect) { super.init(frame: frame) setupGradient() } required init?(coder: NSCoder) { super.init(coder: coder) setupGradient() } private func setupGradient() { guard let gradientLayer = layer as? CAGradientLayer else { return } gradientLayer.colors = [UIColor.red.cgColor, UIColor.green.cgColor] // 设置渐变方向为左上角到右下角 gradientLayer.startPoint = CGPoint(x: 0, y: 0) gradientLayer.endPoint = CGPoint(x: 1, y: 1) } }
内容的提问来源于stack exchange,提问作者sudoExclamationExclamation
相关产品推荐
相关产品推荐

