swift - 内部渐变颜色 UIBezierPath

标签 swift core-graphics uibezierpath swift-playground

我需要用渐变颜色填充我的贝塞尔曲线路径。我可以在图表上填充背景,但不能填充贝塞尔曲线的内容。知道为什么吗?

//: Playground - noun: a place where people can play

import Foundation
import UIKit
import CoreGraphics
import QuartzCore

class DemoView: UIView {
    override func draw(_ rect: CGRect) {
        let origin = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
        let radius = frame.size.width / 2

//        self.createCircle(origin: origin, radius: radius)
        self.addLinesInCircle(origin: origin, radius: radius)
    }

    func createCircle(origin: CGPoint, radius: CGFloat) {
        let path = UIBezierPath()
        path.addArc(withCenter: origin, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
        path.close()
        UIColor.clear.setFill()
        path.fill()
    }

    func addLinesInCircle(origin: CGPoint, radius: CGFloat) {
        let bezier = UIBezierPath()
        let incrementAngle: CGFloat = CGFloat.pi / 24
        let ratios: [CGFloat] = [3/6, 5/6, 3/6, 1/6, 5/6, 2/6, 4/6, 2/6, 4/6, 4/6, 4/6, 4/6,
                                 3/6, 5/6, 3/6, 1/6, 5/6, 2/6, 4/6, 2/6, 4/6, 4/6, 4/6, 4/6,
                                 3/6, 5/6, 3/6, 1/6, 5/6, 2/6, 4/6, 2/6, 4/6, 4/6, 4/6, 4/6,
                                 3/6, 5/6, 3/6, 1/6, 5/6, 2/6, 4/6, 2/6, 4/6, 4/6, 4/6, 4/6]

        for (index, ratio) in ratios.enumerated() {
            let point = CGPoint(x: origin.x + cos(CGFloat(index) * incrementAngle) * radius * ratio,
                                y: origin.y + sin(CGFloat(index) * incrementAngle) * radius * ratio)
            if index == 0 {
                bezier.move(to: point)
            } else {
                bezier.addLine(to: point)
            }
        }
        bezier.close()

        let layer = CAGradientLayer()
            layer.frame = bezier .bounds
            layer.colors = [UIColor.red.cgColor,UIColor.blue.cgColor,UIColor.yellow.cgColor ,UIColor.black.cgColor]

        let mask = CAShapeLayer()
            mask.frame = bezier.bounds
            mask.path = bezier.cgPath
            mask.fillColor = UIColor.black.cgColor

        layer.mask = mask

        self.layer.addSublayer(layer)
        self.layer.addSublayer(mask)
    }
}

let demoView = DemoView(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))

这是结果。我需要恰恰相反,将渐变分配给贝塞尔曲线。 (为了测试我直接用了xcode playground)

enter image description here

最佳答案

一种选择是使用 CGGradient 并使用贝塞尔曲线路径作为裁剪区域。不需要图层。

关闭路径后替换所有内容:

let gradient = CGGradient(colorsSpace: nil, colors: [UIColor.red.cgColor,UIColor.blue.cgColor,UIColor.yellow.cgColor ,UIColor.black.cgColor] as CFArray, locations: nil)!

let ctx = UIGraphicsGetCurrentContext()!
ctx.saveGState()

// Clip to the path
bezier.addClip() 
// Draw the gradient in the clipped region
ctx.drawLinearGradient(gradient, start: CGPoint(x: 0, y: 0), end: CGPoint(x: 0, y: frame.height), options: [])

ctx.restoreGState()

关于swift - 内部渐变颜色 UIBezierPath,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50810563/

相关文章:

swift - 如何在Swift中读取和写入大块内存中的位

objective-c - 构建具有多个可拉伸(stretch)图像的 UIImage

swift - 如何使用Core Graphics快速填充三角形

ios - xCode - 帮助尝试将撤消/重做功能添加到 UIBezierPath

iphone - CGContextSetShadow 不产生任何结果

ios - 如何创建具有超过 1000 条边/线的可移动且可调整大小的多边形?

ios - UIBezierPath 上的点或位置

objective-c - 绘制三角形

ios - Swift iOS,UITableView 无

ios - 如何知道 AVSpeechUtterance 何时结束,以便继续应用事件?