Quartz 2D 的渐变方式分为如下两种:
使用中我们可以直接绘制一个渐变,也可以将渐变填充到现有的图形路径上。下面通过样例分别进行演示。
- 线性渐变:渐变色以直线方式从开始位置逐渐向结束位置渐变
- 放射性渐变:以中心点为圆心从起始渐变色向四周辐射,直到终止渐变色
一、渐变的绘制
1,绘制线性渐变
import
UIKit
class
ViewController
:
UIViewController
{
override
func
viewDidLoad() {
super
.viewDidLoad()
let
frame =
CGRect
(x: 30, y: 30, width: 250, height: 100)
let
cgView =
CGView
(frame: frame)
self
.view.addSubview(cgView)
}
override
func
didReceiveMemoryWarning() {
super
.didReceiveMemoryWarning()
}
}
class
CGView
:
UIView
{
override
init
(frame:
CGRect
) {
super
.
init
(frame: frame)
//设置背景色为透明,否则是黑色背景
self
.backgroundColor =
UIColor
.clear
}
required
init
?(coder aDecoder:
NSCoder
) {
fatalError(
"init(coder:) has not been implemented"
)
}
override
func
draw(_ rect:
CGRect
) {
super
.draw(rect)
//获取绘图上下文
guard
let
context =
UIGraphicsGetCurrentContext
()
else
{
return
}
//使用rgb颜色空间
let
colorSpace =
CGColorSpaceCreateDeviceRGB
()
//颜色数组(这里使用三组颜色作为渐变)fc6820
let
compoents:[
CGFloat
] = [0xfc/255, 0x68/255, 0x20/255, 1,
0xfe/255, 0xd3/255, 0x2f/255, 1,
0xb1/255, 0xfc/255, 0x33/255, 1]
//没组颜色所在位置(范围0~1)
let
locations:[
CGFloat
] = [0,0.5,1]
//生成渐变色(count参数表示渐变个数)
let
gradient =
CGGradient
(colorSpace: colorSpace, colorComponents: compoents,
locations: locations, count: locations.count)!
//渐变开始位置
let
start =
CGPoint
(x:
self
.bounds.minX, y:
self
.bounds.minY)
//渐变结束位置
let
end =
CGPoint
(x:
self
.bounds.maxX, y:
self
.bounds.minY)
//绘制渐变
context.drawLinearGradient(gradient, start: start, end: end,
options: .drawsBeforeStartLocation)
}
}
|
2,绘制放射性渐变
class
CGView
:
UIView
{
override
init
(frame:
CGRect
) {
super
.
init
(frame: frame)
//设置背景色为透明,否则是黑色背景
self
.backgroundColor =
UIColor
.clear
}
required
init
?(coder aDecoder:
NSCoder
) {
fatalError(
"init(coder:) has not been implemented"
)
}
override
func
draw(_ rect:
CGRect
) {
super
.draw(rect)
//获取绘图上下文
guard
let
context =
UIGraphicsGetCurrentContext
()
else
{
return
}
//使用rgb颜色空间
let
colorSpace =
CGColorSpaceCreateDeviceRGB
()
//颜色数组(这里使用三组颜色作为渐变)fc6820
let
compoents:[
CGFloat
] = [0xfc/255, 0x68/255, 0x20/255, 1,
0xfe/255, 0xd3/255, 0x2f/255, 1,
0xb1/255, 0xfc/255, 0x33/255, 1]
//没组颜色所在位置(范围0~1)
let
locations:[
CGFloat
] = [0,0.5,1]
//生成渐变色(count参数表示渐变个数)
let
gradient =
CGGradient
(colorSpace: colorSpace, colorComponents: compoents,
locations: locations, count: locations.count)!
//渐变圆心位置(这里外圆内圆都用同一个圆心)
let
center =
CGPoint
(x:
self
.bounds.midX, y:
self
.bounds.midY)
//外圆半径
let
endRadius =
min
(
self
.bounds.width,
self
.bounds.height) / 2
//内圆半径
let
startRadius = endRadius / 3
//绘制渐变
context.drawRadialGradient(gradient,
startCenter: center, startRadius: startRadius,
endCenter: center, endRadius: endRadius,
options: .drawsBeforeStartLocation)
}
}
|
二、渐变的填充
不管是线性渐变、还是放射性渐变,除了像上面那样直接绘制到背景上外,还可以填充绘制成任何的形状。
首先我们自定义一个要填充的
path,无论是什么形状都可以。接着将其加入到
Context 中,用来做
Clip。最后在绘制渐变即可。
1,填充矩形
通过 context.clip(to: CGRect) 和 context.clip(to: [CGRect]),我们可以很方便的设置矩形的 Clip。下面样例使用后一个方法,在视图上同时添加多个矩形 Clip。
class
CGView
:
UIView
{
override
init
(frame:
CGRect
) {
super
.
init
(frame: frame)
//设置背景色为透明,否则是黑色背景
self
.backgroundColor =
UIColor
.clear
}
required
init
?(coder aDecoder:
NSCoder
) {
fatalError(
"init(coder:) has not been implemented"
)
}
override
func
draw(_ rect:
CGRect
) {
super
.draw(rect)
//获取绘图上下文
guard
let
context =
UIGraphicsGetCurrentContext
()
else
{
return
}
//创建clip矩形
let
rect1 =
CGRect
(x: 0, y: 0,
width:
self
.bounds.width/4, height:
self
.bounds.height/2)
let
rect2 =
CGRect
(x:
self
.bounds.maxX/4, y:
self
.bounds.maxY/2,
width:
self
.bounds.width/4, height:
self
.bounds.height/2)
let
rect3 =
CGRect
(x:
self
.bounds.maxX/2, y: 0,
width:
self
.bounds.width/4, height:
self
.bounds.height/2)
let
rect4 =
CGRect
(x:
self
.bounds.maxX/4*3, y:
self
.bounds.maxY/2,
width:
self
.bounds.width/4, height:
self
.bounds.height/2)
context.clip(to: [rect1, rect2, rect3, rect4])
//使用rgb颜色空间
let
colorSpace =
CGColorSpaceCreateDeviceRGB
()
//颜色数组(这里使用三组颜色作为渐变)fc6820
let
compoents:[
CGFloat
] = [0xfc/255, 0x68/255, 0x20/255, 1,
0xfe/255, 0xd3/255, 0x2f/255, 1,
0xb1/255, 0xfc/255, 0x33/255, 1]
//没组颜色所在位置(范围0~1)
let
locations:[
CGFloat
] = [0,0.5,1]
//生成渐变色(count参数表示渐变个数)
let
gradient =
CGGradient
(colorSpace: colorSpace, colorComponents: compoents,
locations: locations, count: locations.count)!
//渐变开始位置
let
start =
CGPoint
(x:
self
.bounds.minX, y:
self
.bounds.minY)
//渐变结束位置
let
end =
CGPoint
(x:
self
.bounds.maxX, y:
self
.bounds.minY)
//绘制渐变
context.drawLinearGradient(gradient, start: start, end: end,
options: .drawsBeforeStartLocation)
}
}
|
2,填充不规则的图形
要实现不规则形状的填充,可以先创建对应的 path 并添加到上下文中,再通过 context.clip() 方法设置 Clip 即可。下面以实现一个菱形渐变为例。
class
CGView
:
UIView
{
override
init
(frame:
CGRect
) {
super
.
init
(frame: frame)
//设置背景色为透明,否则是黑色背景
self
.backgroundColor =
UIColor
.clear
}
required
init
?(coder aDecoder:
NSCoder
) {
fatalError(
"init(coder:) has not been implemented"
)
}
override
func
draw(_ rect:
CGRect
) {
super
.draw(rect)
//获取绘图上下文
guard
let
context =
UIGraphicsGetCurrentContext
()
else
{
return
}
//创建并设置路径
let
path =
CGMutablePath
()
path.move(to:
CGPoint
(x:
self
.bounds.midX, y:
self
.bounds.minY))
path.addLine(to:
CGPoint
(x:
self
.bounds.maxX, y:
self
.bounds.midY))
path.addLine(to:
CGPoint
(x:
self
.bounds.midX, y:
self
.bounds.maxY))
path.addLine(to:
CGPoint
(x:
self
.bounds.minX, y:
self
.bounds.midY))
path.closeSubpath()
//添加路径到图形上下文
context.addPath(path)
context.clip()
//使用rgb颜色空间
let
colorSpace =
CGColorSpaceCreateDeviceRGB
()
//颜色数组(这里使用三组颜色作为渐变)fc6820
let
compoents:[
CGFloat
] = [0xfc/255, 0x68/255, 0x20/255, 1,
0xfe/255, 0xd3/255, 0x2f/255, 1,
0xb1/255, 0xfc/255, 0x33/255, 1]
//没组颜色所在位置(范围0~1)
let
locations:[
CGFloat
] = [0,0.5,1]
//生成渐变色(count参数表示渐变个数)
let
gradient =
CGGradient
(colorSpace: colorSpace, colorComponents: compoents,
locations: locations, count: locations.count)!
//渐变开始位置
let
start =
CGPoint
(x:
self
.bounds.minX, y:
self
.bounds.minY)
//渐变结束位置
let
end =
CGPoint
(x:
self
.bounds.maxX, y:
self
.bounds.minY)
//绘制渐变
context.drawLinearGradient(gradient, start: start, end: end,
options: .drawsBeforeStartLocation)
}
}
|