【iOS】- Swift 旋轉(zhuǎn)+軌跡動(dòng)畫制作加載頁(yè)面

具體動(dòng)畫
1242701-bc21f72752a5d367.gif

如上圖,動(dòng)畫可以拆分為三部分

  • 1 . 中間扇葉的旋轉(zhuǎn)動(dòng)畫!
  • 2 . 兩邊的畫線軌跡!
  • 3 . 動(dòng)態(tài)變化的進(jìn)度顯示!

中間扇葉動(dòng)畫

我這邊使用的4張圖片,已附上:


>
02.png
03.png
juhua.png

很明顯了是吧,只需要把圖片加上去,然后旋轉(zhuǎn)起來(lái)就可以了。
那么怎么讓它變成旋轉(zhuǎn)的呢?其實(shí)很簡(jiǎn)單,Apple 就已經(jīng)提供給我們很好的API 以供使用!

圖片旋轉(zhuǎn)

聲明部分

    /// 菊花視圖
    lazy var hudImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "bgImage")
        return imageView
    }()
    
    ///葉子視圖1
    lazy var imageView1: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "image01")
        return imageView
    }()
    
    ///葉子視圖2
    lazy var imageView2: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "image02")
        return imageView
    }()
    
    ///葉子視圖3
    lazy var imageView3: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "image03")
        return imageView
    }()
    /// 初始旋轉(zhuǎn)角度
    var angleHud = CGFloat(1);
    var angle1 = CGFloat(1);
    var angle2 = CGFloat(1);
    var angle3 = CGFloat(1);

    /// 是否停止動(dòng)畫
    var isStop = false

旋轉(zhuǎn)圖片實(shí)現(xiàn)方法

    /// 開始圖片動(dòng)畫
    private func startImageView(){
        
        //選擇動(dòng)畫:
        
        let endAnglehud = CGAffineTransform(rotationAngle: angleHud * .pi / 180)
        let endAngle1 = CGAffineTransform(rotationAngle: angle1 * .pi / 180)
        let endAngle2 = CGAffineTransform(rotationAngle: angle2 * .pi / 180)
        let endAngle3 = CGAffineTransform(rotationAngle: angle3 * .pi / 180)
        
        
        UIView.animate(withDuration: 0.01) {
            
            self.hudImageView.transform = endAnglehud
            self.imageView1.transform = endAngle1
            self.imageView2.transform = endAngle2
            self.imageView3.transform = endAngle3
            
        } completion: { finished in
            self.angleHud -= 4;
            self.angle1 += 4;
            self.angle2 -= 4;
            self.angle3 += 4;
//
            if !self.isStop {
                self.startImageView()
            }
        }
    }

圖片旋轉(zhuǎn)實(shí)現(xiàn)并不難,直接使用就可以了,如上
然后需要旋轉(zhuǎn)多少,速度都可以更改以上的參數(shù)進(jìn)行自己喜好調(diào)整

UI加載部分

    /// 菊花內(nèi)容 - 寬高
    let hudSize = CGSize(width: 120, height: 120)

    /// 進(jìn)度Lable
    lazy var progressLable: UILabel = {
        let lable = UILabel()
        lable.textColor = mainColor
        lable.font = UIFont.systemFont(ofSize: 12)
        lable.textAlignment = .center
        lable.text = "0%"
        return lable
    }()
    /// 主顏色
    let mainColor = UIColor(red: 239/255, green: 223/255, blue: 183/255, alpha: 1)
   
 // MARK: - UI實(shí)現(xiàn)
    func loadUI() -> Void {
        
        self.addSubview(bgImageView)
        
        bgImageView.addSubview(imageView1)
        
        bgImageView.addSubview(imageView2)
        
        bgImageView.addSubview(imageView3)
        
        bgImageView.addSubview(hudImageView)
        
        bgImageView.addSubview(progressLable)
        
    }
    
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        bgImageView.frame = self.bounds
        
        imageView1.center = bgImageView.center
        imageView1.frame.size = hudSize
        
        imageView2.center = bgImageView.center
        imageView2.frame.size = hudSize
        
        imageView3.center = bgImageView.center
        imageView3.frame.size = hudSize
        
        hudImageView.center = bgImageView.center
        hudImageView.frame.size = hudSize
        
        progressLable.center = bgImageView.center
        progressLable.frame.size = CGSize(width: 50, height: 50)
        progressLable.layer.cornerRadius = progressLable.frame.height/2
        progressLable.layer.masksToBounds = true
        progressLable.layer.borderColor = progressLable.textColor.cgColor
        progressLable.layer.borderWidth = 0.8
        
    }
    

以上實(shí)現(xiàn)就不需要過(guò)多敘述了,進(jìn)度的使用的是一個(gè)Lable.

那么說(shuō)下,最后一個(gè),前言說(shuō)到的畫線軌跡動(dòng)畫!

很明顯,動(dòng)畫軌跡來(lái)看,一個(gè)直線和一個(gè)半圓,
既然如此,那么就可以按照這個(gè)想法來(lái)進(jìn)行實(shí)現(xiàn)!我們都知道,iOS中有個(gè)很強(qiáng)大的類,UIBezierPath 軌跡畫線!
可供參考的 :
UIBezierPath蘋果官方API文獻(xiàn)
簡(jiǎn)書李國(guó)安的文章

下面就是代碼實(shí)現(xiàn)部分,先貼代碼:
    /// 重寫系統(tǒng) 繪制方法
    override func draw(_ rect: CGRect) {
        
        ///上半部軌跡
        let path = UIBezierPath()
        //起點(diǎn)
        path.move(to: CGPoint(x: self.frame.width, y: self.center.y))
        //直線終點(diǎn)
        path.addLine(to: CGPoint(x: self.center.x+hudSize.width/2, y: self.center.y))
        path.addArc(withCenter: self.center, radius: 60, startAngle: .pi*2, endAngle: .pi*1, clockwise: false)
        
        let caShapelayer = CAShapeLayer()
        caShapelayer.path = path.cgPath
        //線條寬度
        caShapelayer.lineWidth = 1.5
        //線條顏色
        caShapelayer.strokeColor = mainColor.cgColor
        //填充顏色
        caShapelayer.fillColor = UIColor.clear.cgColor
        caShapelayer.frame = self.bounds
        self.layer.addSublayer(caShapelayer)
        

        ///下半部軌跡
        let path2 = UIBezierPath()
        //起點(diǎn)
        path2.move(to: CGPoint(x: 0, y: self.center.y))
        //直線終點(diǎn)
        path2.addLine(to: CGPoint(x: self.center.x-hudSize.width/2, y: self.center.y))
        path2.addArc(withCenter: self.center, radius: 60, startAngle: .pi*1, endAngle: .pi*2, clockwise: false)
        
        let caShapelayer2 = CAShapeLayer()
        caShapelayer2.path = path2.cgPath
        //線條寬度
        caShapelayer2.lineWidth = 1.5
        //線條顏色
        caShapelayer2.strokeColor = mainColor.cgColor
        //填充顏色
        caShapelayer2.fillColor = UIColor.clear.cgColor
        caShapelayer2.frame = self.bounds
        self.layer.addSublayer(caShapelayer2)
        
        
        DispatchQueue.main.async {
            self.drawLineAnimation(layer: caShapelayer)
            self.drawLineAnimation(layer: caShapelayer2)
        }
        
    }

    /// 軌跡動(dòng)畫添加到Self- 軌跡動(dòng)畫
    func drawLineAnimation(layer:CALayer) -> Void {
        
        let bas = CABasicAnimation.init(keyPath: "strokeEnd")
        bas.duration = 3
        bas.delegate = self
        bas.fromValue = 0
        bas.toValue = 1
        layer.add(bas, forKey: "key")
    }
    

總體來(lái)說(shuō),上下部分軌跡,實(shí)際上是一樣的,所以就分析其中一個(gè)就可以了,首先,確定path 軌跡起點(diǎn),拐點(diǎn),和終點(diǎn)!

        ///上半部軌跡
        let path = UIBezierPath()
        //起點(diǎn)
        path.move(to: CGPoint(x: self.frame.width, y: self.center.y))
        //直線終點(diǎn)
        path.addLine(to: CGPoint(x: self.center.x+hudSize.width/2, y: self.center.y))
        //圓路徑
        path.addArc(withCenter: self.center, radius: 60, startAngle: .pi*2, endAngle: .pi*1, clockwise: false)

直線路徑無(wú)需多說(shuō),注釋已經(jīng)很清晰了,主要說(shuō)下,半圓軌跡:

系統(tǒng)方法

        open func addArc(withCenter center: CGPoint,
                         radius: CGFloat,
                         startAngle: CGFloat,
                         endAngle: CGFloat,
                         clockwise: Bool)
  • center : 顧名思義就是圓的中心點(diǎn),學(xué)過(guò)數(shù)學(xué)的都知道!
  • radius: 圓的半徑!
  • startAngle: 圓軌跡起始的弧度!
  • endAngle : 圓軌跡結(jié)束的弧度!
  • clockwise : 是否順時(shí)針!

封裝API,提供外部使用

    /// 單例
    static let shareView = AnimationLoadView()
    
    /// 快捷初始化
    public static func show() -> Void{

        let window = UIApplication.shared.delegate?.window!
        shareView.backgroundColor = .black
        shareView.frame = UIScreen.main.bounds
        window!.addSubview(shareView)
        shareView.start()
    }
    
    
    /// 開始動(dòng)畫
    public func start() -> Void {
        
        startImageView()
        
    }
    
    
    /// 結(jié)束動(dòng)畫
    public func stop() -> Void {
        
        isStop = true
        progressLable.text = "0%"
        self.angleHud = 1;
        self.angle1 = 1;
        self.angle2 = 1;
        self.angle3 = 1;
        self.removeFromSuperview()
    }

至此所有的動(dòng)畫效果都已經(jīng)完成,在有需要的地方進(jìn)行調(diào)用,就可以了!

ps: 不當(dāng)之處還請(qǐng)海涵,分享以及記錄自己的代碼,請(qǐng)不喜勿噴!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容