使用径向渐变作为 UIView 的扩展

Posted

技术标签:

【中文标题】使用径向渐变作为 UIView 的扩展【英文标题】:Use radial gradient as an extention for UIView 【发布时间】:2019-03-04 21:27:49 【问题描述】:

我的目标是为 UIView 做径向渐变扩展。这是我的代码:

extension UIView 
    func drawRadialGradient() 
        let colors = Colors.gradientColors as CFArray
        let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: nil)
        guard let gradientValue = gradient  else return 
        let endRadius: CGFloat? = max(frame.width, frame.height) / 2
        guard let endRadiusValue = endRadius else return 
        let bottomcenterCoordinates = CGPoint(x: frame.width / 2, y: frame.height)
        let getCurrentContext = UIGraphicsGetCurrentContext()
        guard let currentContext = getCurrentContext else return 
        currentContext.drawRadialGradient(gradientValue, startCenter: bottomcenterCoordinates, startRadius: 0.0, endCenter: bottomcenterCoordinates, endRadius: endRadiusValue, options: CGGradientDrawingOptions.drawsAfterEndLocation)
        let radialGradientLayer = CALayer(layer: currentContext)
        radialGradientLayer.frame = bounds
        radialGradientLayer.masksToBounds = true
        self.layer.insertSublayer(radialGradientLayer, at: 1)
    

当我在 viewDidLoad() 或 viewWillAppear() 中调用此函数时,编译器不包含任何错误和警告,但该函数无法正常工作。我称之为:

override func viewDidLoad() 
    super.viewDidLoad()
    view.drawRadialGradient()

例如,我创建了一个在 UIView 上绘制线性渐变的扩展函数,它可以工作,我将其称为径向渐变函数:

func drawLinearGradient() 
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = self.frame
    gradientLayer.colors = Colors.gradientColors
    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.95)
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.05)
    self.layer.insertSublayer(gradientLayer, at: 0)

对于颜色我创建了一个结构:

struct Colors 
    static let firstColor = colorPicker(red: 70, green: 183, blue: 0)
    static let secondColor = colorPicker(red: 0, green: 170, blue: 116)
    static let thirdColor = colorPicker(red: 20, green: 0, blue: 204)
    static let gradientColors = [firstColor.cgColor, secondColor.cgColor, thirdColor.cgColor]
    static func colorPicker(red: CGFloat, green: CGFloat, blue: CGFloat) -> UIColor 
        let color = UIColor(red: red / 255, green: green / 255, blue: blue / 255, alpha: 1.0)
        return color
    

请给我一条关于如何将其实现为扩展的建议。

【问题讨论】:

欢迎来到 ***!为了让人们能够帮助你,你真的应该提供更多信息。 “它不起作用”可能意味着任何事情。所以解释一下哪里出错了。哪些部分有效,哪些无效?例如,当您单步执行代码时,哪一行不符合您的预期。 @fishinear,我已经更新了代码。谢谢你的好意建议。编译器根本不给出任何警告,控制台中也没有消息。我在其中调用此函数的视图像往常一样以白色背景加载。 @Leo Dabus,感谢您对代码风格的审查! 【参考方案1】:

我可以在您的代码中看到的一个主要内容是您尝试在viewDidLoad 中进行绘图。不要那样做,除了其他问题之外,此时还没有正确设置帧大小。如果你想让UIView进行绘图,那么从UIView派生一个类,并在该类的draw方法中进行绘图。

如果你想要你创建的radialGradientLayerCALayer 来进行绘图(它目前只是空的),那么从CALayer 派生一个子类,并实现它的drawInContext 方法。

【讨论】:

以上是关于使用径向渐变作为 UIView 的扩展的主要内容,如果未能解决你的问题,请参考以下文章

CSS3 渐变 — 径向渐变

如何给SVG填充和描边应用径向渐变

使用带有径向渐变的 CAGradientLayer 时出现奇怪的渐变。

如何正确地将 Figma 圆锥(又名径向)渐变转换为 android 矢量可绘制?

Canvas使用渐变之-径向渐变详解

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