ios Swift 中的径向渐变背景

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31853859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:10:06  来源:igfitidea点击:

Radial gradient background in Swift

iosswift

提问by Gugulethu

I have been trying to produce a basic radial gradient background, but without success. I managed to get a linear gradient working as shown with the code below, but I have no idea how to make it radial with different colours - like in the image below. Any help would be greatly appreciated. :)

我一直在尝试制作基本的径向渐变背景,但没有成功。我设法得到一个线性渐变,如下面的代码所示,但我不知道如何用不同的颜色使它呈放射状 - 如下图所示。任何帮助将不胜感激。:)

    let gradientLayer: CAGradientLayer = CAGradientLayer()
    gradientLayer.colors = gradientColors
    gradientLayer.locations = gradientLocations ...

enter image description here

在此处输入图片说明

enter image description here

在此处输入图片说明

采纳答案by Zell B.

Have a look at my implementation of RadialGradientLayer, and feel free to modify it

看看我的 RadialGradientLayer 实现,随意修改

class RadialGradientLayer: CALayer {

   override init(){

        super.init()

        needsDisplayOnBoundsChange = true
    }

     init(center:CGPoint,radius:CGFloat,colors:[CGColor]){

        self.center = center
        self.radius = radius
        self.colors = colors

        super.init()

    }

    required init(coder aDecoder: NSCoder) {

        super.init()

    }

    var center:CGPoint = CGPointMake(50,50)
    var radius:CGFloat = 20
    var colors:[CGColor] = [UIColor(red: 251/255, green: 237/255, blue: 33/255, alpha: 1.0).CGColor , UIColor(red: 251/255, green: 179/255, blue: 108/255, alpha: 1.0).CGColor]

    override func drawInContext(ctx: CGContext!) {

        CGContextSaveGState(ctx)

        var colorSpace = CGColorSpaceCreateDeviceRGB()

        var locations:[CGFloat] = [0.0, 1.0]

        var gradient = CGGradientCreateWithColors(colorSpace, colors, [0.0,1.0])

        var startPoint = CGPointMake(0, self.bounds.height)
        var endPoint = CGPointMake(self.bounds.width, self.bounds.height)

        CGContextDrawRadialGradient(ctx, gradient, center, 0.0, center, radius, 0)

    }

}

In my case I needed it with two colors only and if you need more colors you need to modify locationarray declared in drawInContext. Also after creating object from this class don't forget to call its setNeedsDisplay()otherwise it wont work. Also sometimes I needed different size gradients so thats why you have to pass radius parameter in initializer and the center point of your gradient

在我来说,我需要它只有两种颜色,如果你需要更多的颜色,你需要修改location阵列中声明drawInContext。同样从这个类创建对象后不要忘记调用它,setNeedsDisplay()否则它将无法工作。另外有时我需要不同大小的渐变,所以这就是为什么你必须在初始化程序中传递半径参数和渐变的中心点

回答by Kurt J

Here is an implementation in Swift 3 if you're just looking for a UIView radial gradient background:

如果您只是在寻找 UIView 径向渐变背景,这里是 Swift 3 中的一个实现:

class RadialGradientLayer: CALayer {

    var center: CGPoint {
        return CGPoint(x: bounds.width/2, y: bounds.height/2)
    }

    var radius: CGFloat {
        return (bounds.width + bounds.height)/2
    }

    var colors: [UIColor] = [UIColor.black, UIColor.lightGray] {
        didSet {
            setNeedsDisplay()
        }
    }

    var cgColors: [CGColor] {
        return colors.map({ (color) -> CGColor in
            return color.cgColor
        })
    }

    override init() {
        super.init()
        needsDisplayOnBoundsChange = true
    }

    required init(coder aDecoder: NSCoder) {
        super.init()
    }

    override func draw(in ctx: CGContext) {
        ctx.saveGState()
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let locations: [CGFloat] = [0.0, 1.0]
        guard let gradient = CGGradient(colorsSpace: colorSpace, colors: cgColors as CFArray, locations: locations) else {
            return
        }
        ctx.drawRadialGradient(gradient, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: radius, options: CGGradientDrawingOptions(rawValue: 0))
    }

}



class RadialGradientView: UIView {

    private let gradientLayer = RadialGradientLayer()

    var colors: [UIColor] {
        get {
            return gradientLayer.colors
        }
        set {
            gradientLayer.colors = newValue
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        if gradientLayer.superlayer == nil {
            layer.insertSublayer(gradientLayer, at: 0)
        }
        gradientLayer.frame = bounds
    }

}

回答by ChikabuZ

@IBDesignable class RadialGradientView: UIView {

    @IBInspectable var outsideColor: UIColor = UIColor.red
    @IBInspectable var insideColor: UIColor = UIColor.green

    override func draw(_ rect: CGRect) {
        let colors = [insideColor.cgColor, outsideColor.cgColor] as CFArray
        let endRadius = sqrt(pow(frame.width/2, 2) + pow(frame.height/2, 2))
        let center = CGPoint(x: bounds.size.width / 2, y: bounds.size.height / 2)
        let gradient = CGGradient(colorsSpace: nil, colors: colors, locations: nil)
        let context = UIGraphicsGetCurrentContext()

        context?.drawRadialGradient(gradient!, startCenter: center, startRadius: 0.0, endCenter: center, endRadius: endRadius, options: CGGradientDrawingOptions.drawsBeforeStartLocation)
    }
}

See my full answer here.

在此处查看我的完整答案。

回答by Fattie

2020 - it's now extremely easy to do this:

2020 - 现在非常容易做到这一点:

class GlowBall: UIIView {

    private lazy var pulse: CAGradientLayer = {
        let l = CAGradientLayer()
        l.type = .radial
        l.colors = [ UIColor.red.cgColor,
            UIColor.yellow.cgColor,
            UIColor.green.cgColor,
            UIColor.blue.cgColor]
        l.locations = [ 0, 0.3, 0.7, 1 ]
        l.startPoint = CGPoint(x: 0.5, y: 0.5)
        l.endPoint = CGPoint(x: 1, y: 1)
        layer.addSublayer(l)
        return l
    }()

    override func layoutSubviews() {
        super.layoutSubviews()
        pulse.frame = bounds
        pulse.cornerRadius = bounds.width / 2.0
    }

}

enter image description here

在此处输入图片说明

The key lines are:

关键行是:

        l.colors = [ UIColor.red.cgColor,
            UIColor.yellow.cgColor,
            UIColor.green.cgColor,
            UIColor.blue.cgColor]
        l.locations = [ 0, 0.3, 0.7, 1 ]

Note that you can change the "stretch" as you wish ...

请注意,您可以根据需要更改“拉伸”...

        l.locations = [ 0, 0.1, 0.2, 1 ]

enter image description here

在此处输入图片说明

Use any colors you like

使用任何你喜欢的颜色

        l.colors = [ UIColor.systemBlue.cgColor,
            UIColor.systemPink.cgColor,
            UIColor.systemBlue.cgColor,
            UIColor.systemPink.cgColor,
            UIColor.systemBlue.cgColor,
            UIColor.systemPink.cgColor,
            UIColor.systemBlue.cgColor,
            UIColor.systemPink.cgColor]
        l.locations = [ 0,0.1,0.2,0.3,0.4,0.5,0.6,1 ]

enter image description here

在此处输入图片说明

It's really that easy now.

现在真的很容易。

Very useful trick:

非常有用的技巧:

Say you want yellow, with a blue bandat 0.6:

假设你想要Yellow,在 0.6 处有一条蓝色带

        l.colors = [ UIColor.yellow.cgColor,
            UIColor.blue.cgColor,
            UIColor.yellow.cgColor]
        l.locations = [ 0, 0.6, 1 ]

That works fine.

这很好用。

But usually you do this:

但通常你这样做:

        l.colors = [ UIColor.yellow.cgColor,
            UIColor.yellow.cgColor,
            UIColor.blue.cgColor,
            UIColor.yellow.cgColor,
            UIColor.yellow.cgColor]

Now you can control "how wide"the blue band is:

现在您可以控制蓝带的“宽度”

In this example the blue band will be narrow and sharp:

在这个例子中,蓝色带将窄而锐利:

        l.locations = [ 0, 0.58, 0.6, 0.68, 1 ]

In this example the blue band will be broad and soft:

在这个例子中,蓝带将是宽而柔和的:

        l.locations = [ 0, 0.5, 0.6, 0.7, 1 ]

That is really the secret to how you control gradients, and get the look you want.

这确实是您如何控制渐变并获得所需外观的秘诀。

回答by Gugulethu

Here is a linkfor a really great resource with a range of gradients and blend factors included with some animations. Works in SpriteKit too. ;)

这是一个非常棒的资源的链接,其中包含一些动画中包含的一系列渐变和混合因子。也适用于 SpriteKit。;)

enter image description here

在此处输入图片说明