首页 文章

如何将CAGradientLayer添加到CAShapeLayer?

提问于
浏览
3

我正在尝试将CAGradientLayer添加到CAShapeLayer,但渐变不符合图层的形状 . 相反,渐变呈现出UIView本身的形状 . 我最初尝试使用UIBezierPath,但它也没有用 . 我试图在我的形状中加入渐变 .

override func drawRect(rect: CGRect) {
        let bounds = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
        let center = self.center

        let path = CAShapeLayer()
        path.bounds = bounds
        path.position = CGPoint(x: center.x, y: center.y)
        //path.backgroundColor = UIColor.redColor().CGColor
        path.cornerRadius = 20
        //self.layer.addSublayer(path)
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = path.bounds
        gradientLayer.colors = [cgColorForRed(209.0, green: 0.0, blue: 0.0),
            cgColorForRed(255.0, green: 102.0, blue: 34.0),
            cgColorForRed(255.0, green: 218.0, blue: 33.0),
            cgColorForRed(51.0, green: 221.0, blue: 0.0),
            cgColorForRed(17.0, green: 51.0, blue: 204.0),
            cgColorForRed(34.0, green: 0.0, blue: 102.0),
            cgColorForRed(51.0, green: 0.0, blue: 68.0)]
        gradientLayer.startPoint = CGPoint(x:0,y:0)
        gradientLayer.endPoint = CGPoint(x:0, y:1)
        path.insertSublayer(gradientLayer, atIndex: 1)
        self.layer.addSublayer(path)


    }

    func cgColorForRed(red: CGFloat, green: CGFloat, blue: CGFloat ) -> AnyObject {
        return UIColor(red: red/255.0, green: green/255.0, blue: blue/255.5, alpha: 1.0).CGColor as AnyObject
    }

最初我将路径定义为带圆角的矩形的UIBezierPath,我希望用渐变填充:

let insetRect = CGRectInset(rect, lineWidth / 2, lineWidth / 2)

        let path = UIBezierPath(roundedRect: insetRect, cornerRadius: 10)

        fillColor.setFill()
        path.fill()

        path.lineWidth = self.lineWidth
        UIColor.blackColor().setStroke()
        path.stroke()

根据Larcerax的回复编辑:

class Thermometer: UIView {

    //@IBInspectable var fillColor: UIColor = UIColor.greenColor()
    let lineWidth: CGFloat = 2

    override func drawRect(rect: CGRect) {

        let context = UIGraphicsGetCurrentContext()
        let svgid = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [cgColorForRed(209.0, green: 0.0, blue: 0.0),
            cgColorForRed(255.0, green: 102.0, blue: 34.0),
            cgColorForRed(255.0, green: 218.0, blue: 33.0),
            cgColorForRed(51.0, green: 221.0, blue: 0.0),
            cgColorForRed(17.0, green: 51.0, blue: 204.0),
            cgColorForRed(34.0, green: 0.0, blue: 102.0),
            cgColorForRed(51.0, green: 0.0, blue: 68.0)], [0,1])
        CGContextSaveGState(context)
        let insetRect = CGRectInset(rect, lineWidth / 2, lineWidth / 2)

        let path = UIBezierPath(roundedRect: insetRect, cornerRadius: 10)
        path.addClip()
        CGContextDrawLinearGradient(context, svgid, CGPoint(x: 0, y: path.bounds.height),
            CGPoint(x: path.bounds.width, y: path.bounds.height),
            UInt32(kCGGradientDrawsBeforeStartLocation) | UInt32(kCGGradientDrawsAfterEndLocation))
        CGContextRestoreGState(context)
}

3 回答

  • 1

    产生此输出的@Loxx answer above的第一个形状的 Swift 4 版本:

    @Loxx shape#1
    .

    private func drawShape() {
        guard let context = UIGraphicsGetCurrentContext() else {
            print("No context, handle me")
            return
        }
    
        let gradientColor3 = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
        let gradientColor4 = UIColor(red: 0.000, green: 1.000, blue: 0.000, alpha: 1.000)
    
        guard let sVGID_1_2 = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: [gradientColor3.cgColor, gradientColor4.cgColor] as CFArray, locations: [0, 1]) else {
            print("No gradient, handle me")
            context.restoreGState()
            return
        }
    
        context.saveGState()
        context.translateBy(x: 198.95, y: 199.4)
        context.rotate(by: -30 * CGFloat(Double.pi) / 180)
    
        let polygonPath = UIBezierPath()
        polygonPath.move(to: CGPoint(x: 0, y: -145.95))
        polygonPath.addLine(to: CGPoint(x: 126.4, y: -72.98))
        polygonPath.addLine(to: CGPoint(x: 126.4, y: 72.97))
        polygonPath.addLine(to: CGPoint(x: 0, y: 145.95))
        polygonPath.addLine(to: CGPoint(x: -126.4, y: 72.98))
        polygonPath.addLine(to: CGPoint(x: -126.4, y: -72.97))
        polygonPath.close()
        context.saveGState()
        polygonPath.addClip()
        context.drawLinearGradient(sVGID_1_2,
                                   start: CGPoint(x: -126.4, y: -72.97),
                                   end: CGPoint(x: 126.41, y: 72.99),
                                   options: [.drawsBeforeStartLocation, .drawsAfterEndLocation])
        context.restoreGState()
    }
    

    我发布它是因为基本上每一行都在转换为Swift 4时发生了变化,转换它只需要一段时间来检查它是否有效 .

  • 1

    您可以尝试类似下面的设置以生成以下形状,这只是一个向您展示设置的示例,但是这应该这样做:

    let context = UIGraphicsGetCurrentContext()
    
        let gradientColor3 = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
        let gradientColor4 = UIColor(red: 0.000, green: 1.000, blue: 0.000, alpha: 1.000)
    
        let sVGID_1_2 = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [gradientColor3.CGColor, gradientColor4.CGColor], [0, 1])
    
        CGContextSaveGState(context)
        CGContextTranslateCTM(context, 198.95, 199.4)
        CGContextRotateCTM(context, -30 * CGFloat(M_PI) / 180)
    
        var polygonPath = UIBezierPath()
        polygonPath.moveToPoint(CGPointMake(0, -145.95))
        polygonPath.addLineToPoint(CGPointMake(126.4, -72.98))
        polygonPath.addLineToPoint(CGPointMake(126.4, 72.97))
        polygonPath.addLineToPoint(CGPointMake(0, 145.95))
        polygonPath.addLineToPoint(CGPointMake(-126.4, 72.98))
        polygonPath.addLineToPoint(CGPointMake(-126.4, -72.97))
        polygonPath.closePath()
        CGContextSaveGState(context)
        polygonPath.addClip()
        CGContextDrawLinearGradient(context, sVGID_1_2,
            CGPointMake(-126.4, -72.97),
            CGPointMake(126.41, 72.99),
            UInt32(kCGGradientDrawsBeforeStartLocation) | UInt32(kCGGradientDrawsAfterEndLocation))
        CGContextRestoreGState(context)
    

    产生这个:

    enter image description here

    如果这不起作用,那么告诉我,我会尝试修复它以使其工作 .

    另外,这里只是一个简单的矩形:

    let context = UIGraphicsGetCurrentContext()
    
    let gradientColor = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
    let gradientColor2 = UIColor(red: 0.988, green: 0.933, blue: 0.129, alpha: 1.000)
    let gradientColor3 = UIColor(red: 1.000, green: 0.000, blue: 1.000, alpha: 1.000)
    
    let sVGID_1_3 = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [gradientColor.CGColor, gradientColor2.CGColor, gradientColor3.CGColor], [0, 0.43, 1])
    
    let rectanglePath = UIBezierPath(rect: CGRectMake(68, 28, 78.4, 78.4))
    CGContextSaveGState(context)
    rectanglePath.addClip()
    CGContextDrawLinearGradient(context, sVGID_1_3,
        CGPointMake(68, 67.19),
        CGPointMake(146.38, 67.19),
        UInt32(kCGGradientDrawsBeforeStartLocation) | UInt32(kCGGradientDrawsAfterEndLocation))
    CGContextRestoreGState(context)
    

    enter image description here

    这是一个尝试的功能,你将不得不搞乱颜色,但你可以输入一个框架:

    class func drawStuff(#frame: CGRect) {
            let context = UIGraphicsGetCurrentContext()
    
            let gradientColor = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
            let gradientColor2 = UIColor(red: 0.988, green: 0.933, blue: 0.129, alpha: 1.000)
            let gradientColor3 = UIColor(red: 1.000, green: 0.000, blue: 1.000, alpha: 1.000)
    
            let sVGID_1_4 = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), [gradientColor.CGColor, gradientColor2.CGColor, gradientColor3.CGColor], [0, 0.43, 1])
    
            let rectangleRect = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height)
            let rectanglePath = UIBezierPath(rect: rectangleRect)
            CGContextSaveGState(context)
            rectanglePath.addClip()
            CGContextDrawLinearGradient(context, sVGID_1_4, CGPointMake(rectangleRect.minX, rectangleRect.midY),CGPointMake(rectangleRect.maxX, rectangleRect.midY), 0)
            CGContextRestoreGState(context)
        }
    
  • 5

    或者你可以用我自己写的:) https://github.com/BilalReffas/SwiftyGradient

相关问题