swift - 内部渐变颜色 UIBezierPath
问题描述
我需要用渐变色填充我的贝塞尔路径。我可以填充图表上的背景,但不能填充贝塞尔曲线的内容。知道为什么吗?
//: 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)
解决方案
一种选择是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()
推荐阅读
- java - 引起:org.hibernate.QueryException:无法解析属性:lastUpdateDate of:com.XXX.XXX.entity.Student
- filtering - 将 FILTER 关键字放在 SPARQL 代码块中的哪个位置是否重要?
- mysql - 在 mysql 中,简单的连接查询需要很长时间才能执行
- css - 不看SASS?
- windows-subsystem-for-linux - 如何在 Windows 终端中将 Ubuntu 添加为配置文件选项?
- java - FirebaseJobDispatcher 未触发
- docker - Docker 映像未使用 Helm Chart 使用标签“最新”从 Docker Hub 提取最新映像
- c# - 如何在 asp .net 中获取 Radtime 选择器时间并存储在数据库 sql server 2005 中
- java - 嗨,我已将我的 selenium 脚本与 jenkins 集成,但我无法启动 chrome 浏览器
- c# - EnableCollectionSynchronization 如何工作?