绘制带阴影的渐变圆

时间:2016-09-05 11:54:11

标签: ios swift core-graphics

我想绘制带阴影的渐变圆。 这就是我要的: enter image description here

这就是我得到的:

enter image description here

这是我尝试的代码,但它只绘制没有阴影的渐变圆。

有人可以帮助或解释如何在一个上下文中使用CGContextSetShadowWithColorCGContextDrawLinearGradient来使其正常工作吗?

override func drawRect(rect: CGRect) {
    // context
    let context = UIGraphicsGetCurrentContext()
    // value
    let centerX = rect.width  / 2.0
    let centerY = rect.height / 2.0
    let radius  = rect.width  * 0.33
    // colors
    let shadowColor = UIColor(white: 0.0, alpha: 0.8)        
    // gradient
    CGContextSaveGState(context)

    CGContextSetShadowWithColor(
        context,
        CGSizeMake(0, 0),
        10.0,
        shadowColor.CGColor
    )

    let ellipseRect = CGRectMake(centerX - radius / 2, centerY - radius / 2, radius, radius)
    CGContextAddEllipseInRect(context, ellipseRect)
    CGContextClip(context)


    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let colors: [CGFloat] = [
        // rgba
        44.0 / 255.0, 61.0 / 255.0, 96.0 / 255.0, 1.0,
        09.0 / 255.0, 18.0 / 255.0, 30.0 / 255.0, 1.0
    ]
    let gradient: CGGradientRef = CGGradientCreateWithColorComponents(colorSpace, colors, nil, 2)!
    let gradientStart: CGPoint  = CGPointMake(centerX, centerY - radius / 2);
    let gradientEnd: CGPoint    = CGPointMake(centerX, centerY + radius / 2);
    CGContextDrawLinearGradient(context, gradient, gradientStart, gradientEnd, .DrawsBeforeStartLocation)

    CGContextRestoreGState(context)
}

2 个答案:

答案 0 :(得分:1)

Solved by drawing black circle with shadow first and then draw gradient over that circle.

Here is the code:

override func drawRect(rect: CGRect) {
    if let context = UIGraphicsGetCurrentContext() {
        // values
        let centerX = rect.width  / 2.0
        let centerY = rect.height / 2.0
        let radius  = rect.width  * 0.33
        // colors
        let shadowColor = UIColor(white: 0.0, alpha: 0.8)
        // circle in center with shadow
        let ellipseRect = CGRectMake(centerX - radius / 2, centerY - radius / 2, radius, radius)
        CGContextSaveGState(context)
        CGContextSetShadowWithColor(
            context,
            CGSizeMake(0, 0),
            10.0,
            shadowColor.CGColor
        )
        CGContextFillEllipseInRect(context, ellipseRect)
        CGContextRestoreGState(context)
        // gradient
        let colors: [CGFloat] = [
            // rgba
            44.0 / 255.0, 61.0 / 255.0, 96.0 / 255.0, 1.0,
            09.0 / 255.0, 18.0 / 255.0, 30.0 / 255.0, 1.0
        ]
        CGContextSaveGState(context)
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let gradient: CGGradientRef = CGGradientCreateWithColorComponents(colorSpace, colors, nil, 2)!
        CGContextAddEllipseInRect(context, ellipseRect)
        CGContextClip(context)
        let gradientStart: CGPoint = CGPointMake(centerX, centerY - radius / 2);
        let gradientEnd: CGPoint   = CGPointMake(centerX, centerY + radius / 2);
        CGContextDrawLinearGradient(context, gradient, gradientStart, gradientEnd, .DrawsBeforeStartLocation)
        CGContextRestoreGState(context)
    }
}

答案 1 :(得分:0)

相同代码,兼容Swift 3

override func draw(_ rect: CGRect) {
    if let context = UIGraphicsGetCurrentContext() {
        // values
        let centerX = rect.width  / 2.0
        let centerY = rect.height / 2.0
        let radius  = rect.width  * 0.33
        // colors
        let shadowColor = UIColor(white: 0.0, alpha: 0.8)
        // circle in center with shadow
        let ellipseRect = CGRect(x: centerX - radius / 2, y: centerY - radius / 2, width: radius, height: radius)
        context.saveGState()
        context.setShadow(
            offset: CGSize(width: 0, height: 0),
            blur: 10.0,
            color: shadowColor.cgColor
        )
        context.fillEllipse(in: ellipseRect)
        context.restoreGState()
        // gradient
        let colors: [CGFloat] = [
            // rgba
            44.0 / 255.0, 61.0 / 255.0, 96.0 / 255.0, 1.0,
            09.0 / 255.0, 18.0 / 255.0, 30.0 / 255.0, 1.0
        ]
        context.saveGState()
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let gradient: CGGradient = CGGradient(colorSpace: colorSpace, colorComponents: colors, locations: nil, count: 2)!
        context.addEllipse(in: ellipseRect)
        context.clip()
        let gradientStart: CGPoint = CGPoint(x: centerX, y: centerY - radius / 2);
        let gradientEnd: CGPoint   = CGPoint(x: centerX, y: centerY + radius / 2);
        context.drawLinearGradient(gradient, start: gradientStart, end: gradientEnd, options: .drawsBeforeStartLocation)
        context.restoreGState()
    }
}