美文网首页
MG--Swift遮照HUD 2

MG--Swift遮照HUD 2

作者: Mg明明就是你 | 来源:发表于2022-01-15 00:01 被阅读0次

    MG--Swift遮照HUD 2

    比如网络请求IO读写操作这个操作往往比较耗时这个时候我们往往不需要用户操作这个时候我们就应该提供一个蒙版遮照来防止用户操作就需要用到下面的方法了下面是写的蒙版提示界面我们一般每写的一个界面度会涉及到网络APi请求所以需要HUD


    2种遮照效果

    image
    image

    代码实现如下

    //
    //  MGSquaresAnimationView.swift
    //  MGSDKDemo
    //  Created by LYM-mg on 2021/1/27.
    //  Copyright © 2021 LYM-mg. All rights reserved.
    //
    
    import UIKit
    
    public enum MGSquaresAnimationViewType {
        case Square(animationLayerTintColor: UIColor, squareSize: CGFloat)
        case Circle(ballWidth: CGFloat)
    }
    
    public class MGSquaresAnimationView: UIView {
        convenience init(frame: CGRect = UIScreen.main.bounds, animationViewType: MGSquaresAnimationViewType = .Circle(ballWidth: 13)) {
            self.init(frame: frame)
            switch animationViewType {
                case .Circle(let ballWidth):
                    self._ballWidth = ballWidth
                    self.initBallView()
                    break
                case .Square(let animationLayerTintColor, let squareSize):
                    self.initSquareView()
                    self.animationLayer.frame = self.bounds
                    self.animationLayerTintColor = animationLayerTintColor
                    self.squareSize = squareSize
                    
                    self.setupAnimation()
                    
                    let tintColorRef = animationLayerTintColor.cgColor
                    animationLayer.backgroundColor = tintColorRef
                    break
            }
            self.animationViewType = animationViewType
        }
        
        public override init(frame: CGRect) {
            super.init(frame: frame)
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        deinit {
            print("\(self)--deinit")
        }
        
        // MARK: - Square
        fileprivate var animationLayer: CALayer = CALayer()
        fileprivate var isAnimating: Bool = false
        fileprivate var animationLayerTintColor: UIColor = .white {
            didSet {
                let tintColorRef = animationLayerTintColor.cgColor
                for subLayer in animationLayer.sublayers ?? [] {
                    subLayer.backgroundColor = tintColorRef
                    if subLayer is CAShapeLayer {
    
                        let shapeLayer = CAShapeLayer()
                        shapeLayer.strokeColor = tintColorRef
                        shapeLayer.fillColor = tintColorRef
                    }
                }
            }
        }
        
        fileprivate var squareSize: CGFloat = 60 {
            didSet {
                self.setupAnimation()
            }
        }
        
        fileprivate var animationViewType: MGSquaresAnimationViewType = .Circle(ballWidth: 13)
        
        func initSquareView() {
    //        isUserInteractionEnabled = false
            isHidden = false
            layer.addSublayer(animationLayer)
        }
        
        func startAnimating() {
            switch animationViewType {
                case .Circle(_):
                    startPathAnimation()
                    break
                case .Square(_ , _):
                    if (animationLayer.sublayers != nil) {
                        setupAnimation()
                    }
                    isHidden = false
                    animationLayer.speed = 1.0
                    break
            }
           isAnimating = true
        }
    
        func stopAnimating() {
            switch animationViewType {
                case .Circle(_):
                     ball1.layer.removeAllAnimations()
                     ball1.removeFromSuperview()
                     ball2.layer.removeAllAnimations()
                     ball2.removeFromSuperview()
                     ball3.layer.removeAllAnimations()
                     ball3.removeFromSuperview()
                case .Square(animationLayerTintColor , squareSize):
                    animationLayer.speed = 0.0
                    isHidden = true
                default:
                    break
            }
            isAnimating = false
        }
        
        func setupAnimation() {
    
            animationLayer.sublayers = nil
    
            setupAnimation(layer: animationLayer, with: CGSize(width: self.squareSize, height: self.squareSize), tintColor: self.animationLayerTintColor)
            animationLayer.speed = 0.0
        }
        
        func setupAnimation(layer: CALayer, with size: CGSize, tintColor: UIColor) {
            let beginTime = TimeInterval(CACurrentMediaTime())
    
            let squareSize = floor(size.width / 4.0)
    
            let oX: CGFloat = (layer.bounds.size.width - size.width) / 2.0
            let oY: CGFloat = (layer.bounds.size.height - size.height) / 2.0
            let colors = [
                UIColor(red: 0.880, green: 0.409, blue: 0.195, alpha: 1),
                UIColor(red: 0.137, green: 0.412, blue: 0.663, alpha: 1),
                UIColor(red: 0.810, green: 0.709, blue: 0.115, alpha: 1),
                UIColor(red: 0.537, green: 0.492, blue: 0.363, alpha: 1)
            ]
            
            for i in 0..<5 {
                let square = CALayer()
                square.frame = CGRect(x: oX, y: oY, width: squareSize, height: squareSize)
                square.anchorPoint = CGPoint(x: 0.5, y: 0.5)
                square.backgroundColor = colors[i].cgColor
                square.shouldRasterize = true
                square.rasterizationScale = UIScreen.main.scale
    
                let transformAnimation = createKeyframeAnimation(withKeyPath: "transform")
                transformAnimation.duration = 1.6
                transformAnimation.beginTime = beginTime - (Double(i) * (transformAnimation.duration) / 4.0)
                transformAnimation.repeatCount = MAXFLOAT
    
                transformAnimation.keyTimes = [NSNumber(value: 0.0), NSNumber(value: 0.25), NSNumber(value: 0.50), NSNumber(value: 0.75), NSNumber(value: 1.0)]
                
                transformAnimation.timingFunctions = [
                    CAMediaTimingFunction(name: .easeInEaseOut),
                    CAMediaTimingFunction(name: .easeInEaseOut),
                    CAMediaTimingFunction(name: .easeInEaseOut),
                    CAMediaTimingFunction(name: .easeInEaseOut),
                    CAMediaTimingFunction(name: .easeInEaseOut)
                ]
                
                var t1 = CATransform3DMakeTranslation(size.width - squareSize, 0.0, 0.0)
                t1 = CATransform3DRotate(t1, degreesToRadians(-90.0), 0.0, 0.0, 1.0)
                t1 = CATransform3DScale(t1, 0.7, 0.7, 1.0)
    
                var t2 = CATransform3DMakeTranslation(size.width - squareSize, size.height - squareSize, 0.0)
                t2 = CATransform3DRotate(t2, degreesToRadians(-180.0), 0.0, 0.0, 1.0)
                t2 = CATransform3DScale(t2, 1.0, 1.0, 1.0)
    
                var t3 = CATransform3DMakeTranslation(0.0, size.height - squareSize, 0.0)
                t3 = CATransform3DRotate(t3, degreesToRadians(-270.0), 0.0, 0.0, 1.0)
                t3 = CATransform3DScale(t3, 0.7, 0.7, 1.0)
    
                var t4 = CATransform3DMakeTranslation(0.0, 0.0, 0.0)
                t4 = CATransform3DRotate(t4, degreesToRadians(-360.0), 0.0, 0.0, 1.0)
                t4 = CATransform3DScale(t4, 1.0, 1.0, 1.0)
                
                transformAnimation.values = [
                    NSValue(caTransform3D: CATransform3DIdentity),
                    NSValue(caTransform3D: t1),
                    NSValue(caTransform3D: t2),
                    NSValue(caTransform3D: t3),
                    NSValue(caTransform3D: t4)
                ]
    
                layer.addSublayer(square)
                square.add(transformAnimation, forKey: "animation")
            }
        }
        
        private func degreesToRadians(_ degrees: Double) -> CGFloat {
            return CGFloat((degrees) / 180.0 * Double.pi)
        }
        
        private func createAnimationGroup() -> CAAnimationGroup {
            let animationGroup = CAAnimationGroup()
            animationGroup.isRemovedOnCompletion = false
            return animationGroup
        }
        
        private func createBasicAnimation(withKeyPath keyPath: String?) -> CABasicAnimation {
            let animation = CABasicAnimation(keyPath: keyPath)
            animation.isRemovedOnCompletion = false
            return animation
        }
    
        private func createKeyframeAnimation(withKeyPath keyPath: String?) -> CAKeyframeAnimation {
            let animation = CAKeyframeAnimation(keyPath: keyPath)
            animation.isRemovedOnCompletion = false
            return animation
        }
        
        
        // MARK: - Circle
        var ball1: UIView = UIView()
        var ball2: UIView = UIView()
        var ball3: UIView = UIView()
        var _ballWidth: CGFloat = 13
        var ballContainer: UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
        
        func initBallView() {
            ballContainer.frame = CGRect(x: 0, y: 0, width: 120, height: 120)
            ballContainer.center = CGPoint(x: bounds.size.width / 2.0, y: bounds.size.height / 2.0)
            ballContainer.layer.cornerRadius = 10.0
            ballContainer.layer.masksToBounds = true
            ballContainer.backgroundColor = UIColor.clear
            addSubview(ballContainer)
    
            let margin: CGFloat = 3.0
    
            ball1 = UIView(frame: CGRect(x: 0, y: 0, width: _ballWidth, height: _ballWidth))
            ball1.center = CGPoint(x: _ballWidth / 2.0 + margin, y: ballContainer.bounds.size.height / 2.0)
            ball1.layer.cornerRadius = _ballWidth / 2.0
            ball1.backgroundColor = UIColor(red: 54 / 255.0, green: 136 / 255.0, blue: 250 / 255.0, alpha: 1)
            ballContainer.contentView.addSubview(ball1)
            
            ball2 = UIView(frame: CGRect(x: 0, y: 0, width: _ballWidth, height: _ballWidth))
            ball2.center = CGPoint(x: ballContainer.bounds.size.width / 2.0, y: ballContainer.bounds.size.height / 2.0)
            ball2.layer.cornerRadius = _ballWidth / 2.0
            ball2.backgroundColor = UIColor(red: 100 / 255.0, green: 100 / 255.0, blue: 100 / 255.0, alpha: 1)
            ballContainer.contentView.addSubview(ball2)
    
            ball3 = UIView(frame: CGRect(x: 0, y: 0, width: _ballWidth, height: _ballWidth))
            ball3.center = CGPoint(x: ballContainer.bounds.size.width - _ballWidth / 2.0 - margin, y: ballContainer.bounds.size.height / 2.0)
            ball3.layer.cornerRadius = _ballWidth / 2.0
            ball3.backgroundColor = UIColor(red: 234 / 255.0, green: 67 / 255.0, blue: 69 / 255.0, alpha: 1)
            ballContainer.contentView.addSubview(ball3)
        }
        
        func startPathAnimation() {
            let ballScale: CGFloat = 1.3
            //-------第一个球的动画
            let width = ballContainer.bounds.size.width
            //小圆半径
            let r: CGFloat = (ball1.bounds.size.width) * ballScale / 2.0
            //大圆半径
            let R = (width / 2 + r) / 2.0
    
            let path1 = UIBezierPath()
            path1.move(to: ball1.center)
            //画大圆
            path1.addArc(withCenter: CGPoint(x: R + r, y: width / 2), radius: R, startAngle: .pi, endAngle: .pi * 2, clockwise: false)
            //画小圆
            let path1_1 = UIBezierPath()
            path1_1.addArc(withCenter: CGPoint(x: width / 2, y: width / 2), radius: r * 2, startAngle: .pi * 2, endAngle: .pi, clockwise: false)
            path1.append(path1_1)
            //回到原处
            path1.addLine(to: ball1.center)
            //执行动画
            let positionAnimation = CAKeyframeAnimation(keyPath: "position")
            positionAnimation.path = path1.cgPath
            positionAnimation.isRemovedOnCompletion = false
            positionAnimation.repeatCount = MAXFLOAT
            positionAnimation.duration = 1.6
            positionAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
            ball1.layer.add(positionAnimation, forKey: "animation1")
            
            
            //-------第三个球的动画
            let path3 = UIBezierPath()
            path3.move(to: ball3.center)
            //画大圆
            path3.addArc(withCenter: CGPoint(x: width - (R + r), y: width / 2), radius: R, startAngle: 2 * .pi, endAngle: .pi, clockwise: false)
            //画小圆
            let path3_1 = UIBezierPath()
            path3_1.addArc(withCenter: CGPoint(x: width / 2, y: width / 2), radius: r * 2, startAngle: .pi, endAngle: .pi * 2, clockwise: false)
            path3.append(path3_1)
            //回到原处
            path3.addLine(to: ball3.center)
            //执行动画
            let animation3 = CAKeyframeAnimation(keyPath: "position")
            animation3.path = path3.cgPath
            animation3.repeatCount = MAXFLOAT
            animation3.isRemovedOnCompletion = false
            animation3.duration = 1.6
            animation3.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
            ball3.layer.add(animation3, forKey: "animation3")
            
            // 放大缩小动画
            let scaleAnimation = createBasicAnimation(withKeyPath: "transform.scale")
            scaleAnimation.fromValue = 1.0
            scaleAnimation.toValue = 1.3
            scaleAnimation.duration = 1.6/2
            scaleAnimation.isRemovedOnCompletion = false
            scaleAnimation.repeatCount = MAXFLOAT
            scaleAnimation.autoreverses = true
            scaleAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
            ball1.layer.add(scaleAnimation, forKey: "scale")
            ball2.layer.add(scaleAnimation, forKey: "scale")
            ball3.layer.add(scaleAnimation, forKey: "scale")
        }
    }
    

    调用

    let view = MGSquaresAnimationView(animationViewType: .Square(animationLayerTintColor: UIColor.red, squareSize: 60))
    //        let view = MGSquaresAnimationView(animationViewType: .Circle(ballWidth: 30))
    self.view.addSubview(view)
    view.startAnimating()        
    DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
         view.stopAnimating()
         view.removeFromSuperview()
    }
    

    相关文章

      网友评论

          本文标题:MG--Swift遮照HUD 2

          本文链接:https://www.haomeiwen.com/subject/yxszcrtx.html