You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 09:19:51