iOS-UI之遮罩效果(1)——渐变色底色、简易示波器
来看看实现步骤
1.先绘制一个渐变色的背景Layer
let bgView = UIView()
bgView.frame = bounds
addSubview(bgView)
bgView.layer.masksToBounds = true
let bgGradientLayer = CAGradientLayer()
bgGradientLayer.frame = bgView.bounds
bgGradientLayer.colors = [UIColor.red.cgColor, UIColor.yellow.cgColor, UIColor.cyan.cgColor]
bgGradientLayer.startPoint = CGPoint(x: 0, y: 0)
bgGradientLayer.endPoint = CGPoint(x: 1, y: 0)
bgView.layer.addSublayer(bgGradientLayer)
此时渐变色背景添加好了,如图
2.添加一条线
let lineLayer = CAShapeLayer()
lineLayer.lineWidth = 10
lineLayer.strokeColor = UIColor.lightGray.cgColor
lineLayer.fillColor = UIColor.clear.cgColor
let bezier = UIBezierPath()
bezier.move(to: CGPoint(x: 0, y: bgView.bounds.size.height / 2))
bezier.addLine(to: CGPoint(x: bgView.bounds.size.width, y: bgView.bounds.size.height / 2))
lineLayer.path = bezier.cgPath
bgView.layer.addSublayer(lineLayer)
3.让这条线成为遮罩
将这句
bgView.layer.addSublayer(lineLayer)
替换为
bgGradientLayer.mask = lineLayer
效果如下
到这里,渐变色底色的简易遮罩效果就完成了。
4.将这条遮罩线条变成波形图
仔细观察波形图,其实就是三角函数的波形,则我们可以利用三角函数来画出来
首先删除这几句
let bezier = UIBezierPath()
bezier.move(to: CGPoint(x: 0, y: bgView.bounds.size.height / 2))
bezier.addLine(to: CGPoint(x: bgView.bounds.size.width, y: bgView.bounds.size.height / 2))
lineLayer.path = bezier.cgPath
之前的轨迹是一条直线,而我们现在需要用三角函数来作为它的轨迹
三角函数公式
y=Asin(ωx+φ)+k
A——振幅,当物体作轨迹符合正弦曲线的直线往复运动时,其值为行程的1/2。
(ωx+φ)——相位,反映变量y所处的状态。
φ——初相,x=0时的相位;反映在坐标系上则为图像的左右移动。
k——偏距,反映在坐标系上则为图像的上移或下移。
ω——角速度, 控制正弦周期(单位弧度内震动的次数)
设置属性
private var waveAmplitude:CGFloat = 30 // 曲线振幅
private var wavePalstance:CGFloat = 0 // 曲线角速度
private var waveX:CGFloat = 0 // 曲线初相
private var waveY:CGFloat = 0 // 曲线偏距
private var waveSpeed:CGFloat = 0 // 曲线速度
将公式转化为代码
waveX += waveSpeed
// 波浪宽度
let waveWidth = bgView.bounds.size.width + lineWidth
let path = UIBezierPath()
path.move(to: CGPoint(x: -lineWidth / 2, y: waveY))
// 初始化波浪起始y为偏距
var y:CGFloat = waveY
var x:CGFloat = -lineWidth / 2
while x <= waveWidth {
y = waveAmplitude * sin(wavePalstance * x + waveX) + waveY
path.addLine(to: CGPoint(x: x, y: y))
x += 1
}
lineLayer.path = path.cgPath
此时的图形是静态的,如下图
让波形动起来
为了让图形动起来,我们就需要不停得重绘这个波形,可以把绘制三角函数波形图的代码放到定时器方法里面。
但是,为了避免图形看起来很卡顿,我么可以考虑用CADisplayLink,以屏幕刷新间隔作为重绘图形的周期,这样看起来就会比较流畅了
var displayLink:CADisplayLink? // 定时刷新器
displayLink = CADisplayLink(target: self, selector: #selector(updateWave))
displayLink?.add(to: RunLoop.main, forMode: .common)
@objc func updateWave() {
waveX += waveSpeed
// 波浪宽度
let waveWidth = bgView.bounds.size.width + lineWidth
let path = UIBezierPath()
path.move(to: CGPoint(x: -lineWidth / 2, y: waveY))
// 初始化波浪起始y为偏距
var y:CGFloat = waveY
var x:CGFloat = -lineWidth / 2
while x <= waveWidth {
y = waveAmplitude * sin(wavePalstance * x + waveX) + waveY
path.addLine(to: CGPoint(x: x, y: y))
x += 1
}
lineLayer.path = path.cgPath
}
到这里,波形图就动起来了
示波器Demo
我们还可以将这个做成示波器Demo,将正弦函数的几个参数暴露出来,可以在外面任意修改,如图