如何修复不一致的颜色到清晰的径向渐变层

Posted

技术标签:

【中文标题】如何修复不一致的颜色到清晰的径向渐变层【英文标题】:How to fix inconsistent color-to-clear radial gradient layer 【发布时间】:2018-12-28 12:58:40 【问题描述】:

当尝试绘制从白色到透明的径向渐变时,根据我使用的是UIColor(white:alpha:)UIColor.white.withAlpha.Components(alpha:) 还是UIColor.color,我会获得不同的结果。如何获得与纯色相同的渐变色?

我为了绘制径向渐变,我已经覆盖了 draw(context:) 方法(见下文)。当使用纯色作为渐变时,我的代码似乎可以正常工作,但在使用清晰颜色时“神秘”地工作。

override func draw(in ctx: CGContext) 
    super.draw(in: ctx)

    ctx.saveGState()
    let gradient                = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colorFill as CFArray, locations: self.locations as! [CGFloat] )
    let startPoint              = CGPoint(x: startX, y: startY )
    let endPoint                = CGPoint(x: endX , y: endY)
    let drawingOption           : CGGradientDrawingOptions = radius > 0 ? [] : .drawsAfterEndLocation

    //self.masksToBounds          = true
    if gradientType == .radial 
        ctx.drawRadialGradient(gradient!, startCenter: startPoint, startRadius: 0.0, endCenter: endPoint, endRadius: self.frame.width / 2, options: drawingOption)
     else 
        self.startPoint = startPoint
        self.endPoint   = endPoint
    

这是我根据渐变的输入颜色获得的结果:

[UIColor.white.cgColor,UIColor.black.cgColor] (想要的结果是清晰的颜色而不是黑色)

[UIColor.white.cgColor, UIColor.clear.cgColor]

[UIColor.white.cgColor, UIColor.white.withAlphaComponent(0.0).cgColor]

[UIColor(white: 0.0, alpha: 1).cgColor, UIColor(white: 1.0, alpha: 0).cgColor]

谁能解释为什么我没有得到与仅使用纯色相同的输出(我希望获得的输出)?

非常感谢您花时间阅读和回复!

【问题讨论】:

希望对您有所帮助-> ***.com/questions/31853859/… 感谢您的回复@dahiya_boy。这个话题我早就知道了,我的draw方法也基本一样了。 问题解决了! 我稍后会发布更新,但简而言之,我来确认我的图层被绘制了两次(你可以看到黑白照片中的一点白色),正如我实际上所怀疑的那样。在我的init' method I was setting self.colors` 和self.locations 中,实际上在draw(in context) 方法可以重绘之前绘制图层。通过将信息保存在单独的类型属性中,我可以防止图层的第一次绘制,从而获得足够的结果! 【参考方案1】:

图层不仅在draw(in context:) 方法中绘制。这行代码确认在调用方法之前已经设置了一些属性,这已经触发了图层的绘制(self.locations)

CGColorSpaceCreateDeviceRGB(), colors: colorFill as CFArray, locations: self.locations as! [CGFloat] )

通过在自定义初始化程序中删除 self.colors 和 self.locations 属性集并将值存储在类型属性中,而不是在调用 self.setNeedDisplay() 之前,仅在 draw(in context:) 方法中绘制图层。

class CustomLayer 
    override init() 
        super.init()
        needsDisplayOnBoundsChange = true
    
    
    override init(layer: Any) 
        super.init(layer: layer)
    
    
    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)
    
    
    var colors    = []()
    var colorMap  = [NSNumber]()
    
    custom init() 
      colors = [color,color]
      colorMap = [0.0, 1.0]
      self.setNeedDisplay()
    
    
    override func draw(in ctx: CGContext) 
        super.draw(in: ctx)
        ctx.saveGState()
        guard let gradient          = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: colors as CFArray, locations: colorMap as! [CGFloat] ) else return
        let startPoint              = CGPoint(x: startX, y: startY )
        let endPoint                = CGPoint(x: endX , y: endY)
        self.masksToBounds          = true
        if gradientType == .radial 
            ctx.drawRadialGradient(gradient, startCenter: startPoint, startRadius: 0.0, endCenter: endPoint, endRadius: self.frame.width / 2, options: drawingOption)
         else 
            self.locations          = colorMap
            self.colors             = colors
            self.startPoint         = startPoint
            self.endPoint           = endPoint
        
    

干杯!

【讨论】:

以上是关于如何修复不一致的颜色到清晰的径向渐变层的主要内容,如果未能解决你的问题,请参考以下文章

在 UIImage 上使用 Core Graphic 绘制渐变结果不一致

渐变子层不透明度

线性渐变与径向渐变与重复渐变

如何使径向渐变在 Safari 中起作用?

CSS3之径向渐变

Android UIPaint Gradient 渐变渲染 ③ ( RadialGradient 环形渐变渲染 | 在给定中心和半径的情况下绘制径向渐变的着色器 | 水波纹效果 )