class WaveView: UIView {
var firstWaveColor = UIColor() // 第一個波浪顏色
var secondWaveColor = UIColor() // 第二個波浪顏色
var waveDisplaylink : CADisplayLink!
var firstWaveLayer : CAShapeLayer! // 第一個波浪
var secondWaveLayer : CAShapeLayer! // 第二個波浪
var waveAmplitude : CGFloat = 0.0 // 波紋振幅
var waveCycle : CGFloat = 0.0 // 波紋週期
var waveSpeed : CGFloat = 0.0 // 波紋速度
var offsetX : CGFloat = 0.0 // 波浪 x 位移
var currentWavePointY : CGFloat = 0.0 // 當前波浪上市高度Y(高度從大到小 座標系向下增長
var variable : Float = 0.0 // 可變引數 更加真實 模擬波紋
var increase : Bool = true // 增減變化
var waterWaveWidth : CGFloat = 0.0 // 水波寬度
override func awakeFromNib() {
super.awakeFromNib()
setUp()
}
override init(frame: CGRect) {
super.init(frame: frame)
setUp()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setUp()
}
private func setUp() {
self.backgroundColor = UIColor.clearColor()
firstWaveColor = UIColor.whiteColor()
secondWaveColor = UIColor.whiteColor()
dispatch_async(dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL)) {
self.startWave()
}
waveCycle = 2 * CGFloat(M_PI) / self.frame.size.width
waterWaveWidth = UIScreen.mainScreen().bounds.size.width + 10
waveSpeed = CGFloat(0.05 / M_PI)
currentWavePointY = 0
variable = 1.6
increase = false
offsetX = 0
}
func startWave() {
if firstWaveLayer == nil {
// 建立第一個波浪
firstWaveLayer = CAShapeLayer()
firstWaveLayer.fillColor = firstWaveColor.CGColor
firstWaveLayer.opacity = 0.3
self.layer.addSublayer(firstWaveLayer)
}
if secondWaveLayer == nil {
// 建立第二個波浪
secondWaveLayer = CAShapeLayer()
secondWaveLayer.fillColor = secondWaveColor.CGColor
self.layer.addSublayer(secondWaveLayer)
}
if waveDisplaylink == nil {
// 啟動呼叫定時器
waveDisplaylink = CADisplayLink(target: self, selector:
waveDisplaylink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}
}
@objc private func getCurrentWave(displayLink: CADisplayLink) {
// 這裡是調整波浪狀態,自行發揮
// if (increase) {
// variable += 0.01
// } else {
// variable -= 0.01
// }
// if (variable <= 1) {
// increase = true
// }
//
// if (variable >= 1.6) {
// increase = false
// }
waveAmplitude = CGFloat(variable * 2.5)
offsetX += waveSpeed
setCurrentFirstWaveLayerPath()
setCurrentSecondWaveLayerPath()
}
private func setCurrentFirstWaveLayerPath() {
let path = CGPathCreateMutable()
var y = currentWavePointY
var x : CGFloat = 0.0
CGPathMoveToPoint(path, nil, 0, 0)
while (true) {
y = waveAmplitude * sin(waveCycle * x + offsetX) + currentWavePointY
CGPathAddLineToPoint(path, nil, x, y)
x += 1
if x >= waterWaveWidth {
break
}
}
CGPathAddLineToPoint(path, nil, waterWaveWidth, self.frame.size.height)
CGPathAddLineToPoint(path, nil, 0, self.frame.size.height)
CGPathCloseSubpath(path)
firstWaveLayer.path = path
}
private func setCurrentSecondWaveLayerPath() {
let path = CGPathCreateMutable()
var y = currentWavePointY
var x : CGFloat = 0.0
CGPathMoveToPoint(path, nil, 0, 0)
while (true) {
y = waveAmplitude * cos(waveCycle * x + offsetX) + currentWavePointY
CGPathAddLineToPoint(path, nil, x, y)
x += 1
if x >= waterWaveWidth {
break
}
}
CGPathAddLineToPoint(path, nil, waterWaveWidth, self.frame.size.height)
CGPathAddLineToPoint(path, nil, 0, self.frame.size.height)
CGPathCloseSubpath(path)
secondWaveLayer.path = path
}
deinit {
reset()
}
private func reset() {
if firstWaveLayer != nil {
firstWaveLayer.removeFromSuperlayer()
firstWaveLayer = nil
}
if secondWaveLayer != nil {
secondWaveLayer.removeFromSuperlayer()
secondWaveLayer = nil
}
}
}
複製程式碼