为了使界面看起来高大上,很多app都会加入各种各样的动态效果。本篇文章就简单谈谈波浪效果的实现,效果如下所示:
实现的大体思路就是在UIView的layer上面添加2个CAShapeLayer的子layer,当然如果只是需要一层波浪效果的话只添加一个CAShapeLayer即可。设置好shapeLayer的fillColor,剩下的就是确定范围,即path。
实现shapeLayer的不规则轨迹就是更改path属性,一般是通过UIBezierPath或CGPath来给path赋值。本文就是通过UIBezierPath来实现轨迹。
现在顶部波纹的曲线基本都是在正玄曲线和余弦曲线的基础上变幻而来的。以正弦函数y=Asin(ωx+φ)+h为例,通过修改φ来实现水平位移,通过修改h来实现垂直位移,而且为了更贴近真实波浪效果,一般都会是振幅即A随时间在小范围内波动。这样解决了轨迹的顶部曲线后,剩下的就是3条直线了,通过这4条线就能确定CAShapeLayer的范围了。确定path的相关代码如下所示:
//刷新前面的waveLayer
private func updateFrontWaveLayer() {
let path = UIBezierPath()
path.moveToPoint(CGPoint(x: 0, y: currentWavePointY))
for i in 0...Int(waveWidth) {
let x = CGFloat(i)
let y = waveAmplitude * sin(waveCycle*x + offsetX) + currentWavePointY
path.addLineToPoint(CGPoint(x: x, y: y))
}
path.addLineToPoint(CGPoint(x: waveWidth, y: waveHeight))
path.addLineToPoint(CGPoint(x: 0, y: waveHeight))
path.closePath()
frontWaveLayer?.path = path.CGPath
}
要使波浪一直运动就要一直改变CAShapeLayer的path,也就是要不停调用某个方法来实现layer path属性的改变。这里大家第一时间想到的肯定是NSTimer,但是因为这是属于UI的不停重绘,因此用CADisplayLink相对来说好一些(CADisplayLink的只是可以查看这篇大神写的文章《CADisplayLink》)
最后奉上完整的代码,当然这个demo只是提供一个思路,写的比较简陋,大家可以结合自己的需求另行封装一个完美的WaveView。Demo