带水波纹进度条简单实现

今天要给大家讲解的是关于水波纹的进度条的实现。

学习此文章需要了解一下知识点:

1.正弦或者余弦函数的一点点的了解

2.贝塞尔去曲线,不是很了解的可以阅读笔者的贝塞尔精讲

好了,废话不多说,直接上效果图:

带水波纹进度条简单实现_第1张图片

下面笔者将以代码方式来梳理此效果的逻辑

1.画一个圆形,代码如下:

 func configUI(frame : CGRect){
        //圆
        let path = UIBezierPath(roundedRect: frame, cornerRadius: frame.size.width/2)
        inCirleLayer.strokeColor = UIColor.lightGray.cgColor
        inCirleLayer.fillColor = UIColor.clear.cgColor
        inCirleLayer.path = path.cgPath
        inCirleLayer.lineWidth = 2
        inCirleLayer.lineCap = kCALineCapRound
        self.layer.addSublayer(inCirleLayer)
        
        
        //设置水波纹
        firstWaveLayer.fillColor = UIColor.init(colorLiteralRed: 69/255.0, green: 255/255.0, blue: 255/255.0, alpha: 0.5).cgColor
        secondWaveLayer.fillColor = UIColor.init(colorLiteralRed: 69/255.0, green: 255/255.0, blue: 255/255.0, alpha: 0.5).cgColor
        self.layer.addSublayer(firstWaveLayer)
        self.layer.addSublayer(secondWaveLayer)
        waveDisplaylink = CADisplayLink(target: self, selector: #selector(getCurrentWave))
        waveDisplaylink.add(to: RunLoop.current, forMode: .commonModes)
    }
解释一下,上面是画一个圆心。下面的第对水波纹的做基础的一些设置,同时也设置定时器。代码比较简单

2.基本的参数设置

    //MARK: - 数据的初始化
    private func initData(){
        waveSpeedH = 0.2
        waveSpeed = 0.15
        waveA = 1.25
        // 设置周期 :( 2* M_PI)/waveW = bounds.size.width 。因为涉及的是layer,所以只谈bounds,不说frame
        waveW = 2 * CGFloat(M_PI) / (bounds.size.width / 3)
        b  = (rect?.size.height)!
    }
这里面笔者不去讲解一些Swift的属性等设置

3.重点来了

    func getCurrentWave(){
        if (b >= (rect?.size.height)!/4) {
            b = b - waveSpeedH
        }
        offsetX += waveSpeed
        setCurrentStatusWavePath()
    }
    //MARK: - 关键部分
    private func setCurrentStatusWavePath() {
        // 创建一个路径
        let firstPath = CGMutablePath()
        var firstY = bounds.size.width/2
        firstPath.move(to: CGPoint(x: 0, y: b))
        for i in 0...Int(bounds.size.width) {
            firstY = waveA * sin(waveW * CGFloat(i) + offsetX) + b
            firstPath.addLine(to: CGPoint(x: CGFloat(i), y: firstY))
        }
        
        firstPath.addLine(to: CGPoint(x: bounds.size.width, y: bounds.size.height))
        firstPath.addLine(to: CGPoint(x: 0, y: bounds.size.height))
        firstPath.closeSubpath()
        firstWaveLayer.path = firstPath
        
        // 创建一个路径
        let secondPath = CGMutablePath()
        var secondY = bounds.size.width/2
        secondPath.move(to: CGPoint(x: 0, y: b))
        
        for i in 0...Int(bounds.size.width) {
            secondY = waveA * sin(waveW * CGFloat(i) + offsetX - bounds.size.width/2 ) + b
            secondPath.addLine(to: CGPoint(x: CGFloat(i), y: secondY))
        }
        
        secondPath.addLine(to: CGPoint(x: bounds.size.width, y: bounds.size.height))
        secondPath.addLine(to: CGPoint(x: 0, y: bounds.size.height))
        secondPath.closeSubpath()
        secondWaveLayer.path = secondPath
    }

笔者不在一一讲解上面的代码,只是讲解一下主要的思路,设置好高度,画一条正弦或者余弦函数,然后就是再设置其高度,这样一来,一条静态的正弦或者余弦函数的水波纹就出来了,然后带动态的设置高度,这样一来就出来了。

总结:

是不是很简单啊,感觉简单的话,可以给笔者点个赞

Demo下载链接:https://github.com/WSmalan/ProgressCirle

你可能感兴趣的:(iOS,Swift,动画,贝塞尔曲线)