美文网首页UI随便
Swift实现圆盘效果

Swift实现圆盘效果

作者: 玉思盈蝶 | 来源:发表于2020-07-03 23:52 被阅读0次

    最近项目要实现这么一个有趣味性的功能,网上找了一个Demo是OC实现的,自己项目是Swift的,下面是自己的参考实现。

    实现效果如下:

    image.png image.png

    暂时只是做了一个Demo,点击屏幕加外围的圈。

    代码如下:

    Roundview:

    import UIKit
    
    enum RoundviewType: Int {
        case RoundviewTypeSystem = 0
        case RoundviewTypeCustom = 1
    }
    
    typealias JumpBlock = ((String, String ) -> Void)
    
    class Roundview: UIView {
        var block: JumpBlock?
        var type: RoundviewType = .RoundviewTypeSystem
        var viewWidth: CGFloat?
    
        var btnArray: [UIButton]!
        var btnArray2: [UIButton]!
        
        var rotationAngleInRadians: CGFloat = 0.0
        var isShow: Bool = false
        var nameArray: [String]?
        var outSideArray: [String]?
        var titlesArray: [String]?
        var imageArray: [String]?
        var buttonWidth: CGFloat = 0.0
        var buttonConrenrRadius: CGFloat = 0.0
        var cycleLineRadius: CGFloat = 0.0
        var corner1: CFloat = 0.0
        var corner2: CFloat = 0.0
        var r1: CFloat = 0.0
        var r2: CFloat = 0.0
        var circleCenter: CGPoint!
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.layer.masksToBounds = true
            self.layer.cornerRadius = self.frame.width / 2.0
            self.viewWidth = self.frame.width
            btnArray = []
            btnArray2 = []
            nameArray = []
            self.addGestureRecognizer(RotationGestureRecognizer(target: self, action: #selector(changeMove(rotation:))))
        }
        
        func configure(type: RoundviewType, btnWidth: CGFloat, adjustsFontSizesTowidth: Bool, masksToBounds: Bool, conrenrRadius: CGFloat, images: [String], titileArray: [String], titileColor: UIColor, cycleLineRadius: CGFloat) {
            self.titlesArray = titileArray
            self.imageArray = images
            self.buttonWidth = btnWidth
            self.cornerRadius = cornerRadius
            self.cycleLineRadius = cycleLineRadius
            self.type = type
            let buttonWidth2 = buttonWidth / 2.0
    
            self.corner1 = CFloat(CGFloat(M_PI * 2.0 / Double(titileArray.count)))
            self.r1 = CFloat((self.viewWidth!  - buttonWidth) / 2)
            self.corner2 = self.corner1
            self.r2  = CFloat(cycleLineRadius / 2.0)
            
            nameArray = titileArray;
            self.circleCenter = CGPoint(x: self.bounds.size.width/2.0, y: self.bounds.size.width/2.0)
            // 内圈
            for (i, _) in titileArray.enumerated() {
                let btn = UIButton(type: .custom)
                btn.frame = CGRect(x: 0, y: 0, width: btnWidth, height: btnWidth)
                btn.layer.masksToBounds = true
                btn.layer.cornerRadius = buttonWidth2 / 2.0
                let offsetx2: CGFloat = CGFloat(self.r2 * cos(self.corner2 * Float(i) + Float(M_PI_2)))
                let offsety2 = self.r2 * sin(self.corner2 * Float(i) + Float(M_PI_2))
                btn.center = CGPoint(x: self.circleCenter.x - offsetx2, y: self.circleCenter.y - CGFloat(offsety2))
                if (type == .RoundviewTypeCustom) {
                    let imageView: UIImageView = UIImageView(image: UIImage(named: images[I]))
                    imageView.contentMode = .scaleAspectFit
                    imageView.isUserInteractionEnabled = false
                    imageView.frame = CGRect(x: 25, y: 5, width: 30, height: 30)
                    btn.addSubview(imageView)
                    let label = UILabel(frame: CGRect(x: 10, y: imageView.frame.maxY + 5, width: self.buttonWidth - 20, height: 20))
                    label.text = titileArray[i]
                    label.font = UIFont.systemFont(ofSize: 10)
                    label.textColor = UIColor.black
                    label.textAlignment = .center
                    label.adjustsFontSizeToFitWidth = true
                    label.tag = I
                    btn.addSubview(label)
                } else {
                    btn.setTitle(titileArray[i], for: .normal)
                    btn.setTitleColor(titileColor, for: .normal)
                }
                btn.tag = I
                btn.addTarget(self, action: #selector(btnClick(btn:)), for: .touchUpInside)
                self.addSubview(btn)
                btnArray2.append(btn)
            }
            
            let circle = CAShapeLayer()
            circle.fillColor = UIColor.clear.cgColor
            circle.strokeColor = UIColor.gray.cgColor
            circle.lineWidth = 1.0
            circle.path = UIBezierPath(arcCenter: self.circleCenter, radius: self.cycleLineRadius / 2, startAngle: 0.0, endAngle: CGFloat(M_PI * 2), clockwise: true).cgPath
            //注掉这行可以去除那个圆
            layer.addSublayer(circle)
        }
        
        func show() {
            if (self.isShow) {
                UIView.animate(withDuration: 0.5, animations: {
                    for (i, _) in self.btnArray.enumerated() {
                        let btn: UIButton = self.btnArray[I]
                        let offsetx = self.r1 * cos(self.corner1 * Float(i) + Float(M_PI_2))
                        let offsety = self.r1 * sin(self.corner1 * Float(i) + Float(M_PI_2))
                        btn.center = CGPoint(x: self.circleCenter.x - CGFloat(offsetx), y: self.circleCenter.y - CGFloat(offsety))
                        btn.alpha = 1
                        let btn2: UIButton = self.btnArray2[I]
                        let offsetx2 = self.r2 * cos(self.corner2 * Float(i) + Float(M_PI_2))
                        let offsety2 = self.r2 * sin(self.corner2 * Float(i) + Float(M_PI_2))
                        btn2.center = CGPoint(x: self.circleCenter.x - CGFloat(offsetx2), y: self.circleCenter.y - CGFloat(offsety2))
                        btn2.alpha = btn.alpha
                    }
                }, completion: nil)
            } else {
                UIView.animate(withDuration: 0.5) {
                    for (index, _) in self.btnArray.enumerated() {
                        let btn: UIButton = self.btnArray[index]
                        btn.center = self.circleCenter
                        btn.alpha = 0
                        let btn2: UIButton = self.btnArray2[index]
                        btn2.center = self.circleCenter
                        btn2.alpha = btn.alpha
                    }
                }
            }
            self.isShow = !self.isShow
        }
        
        func addRound2View(titileArray: [String], images: [String], conrenrRadius: CGFloat, btnWidth: CGFloat ) {
            self.outSideArray = titileArray
            for (i, _) in titileArray.enumerated() {
                let btn = UIButton(type: .custom)
                btn.frame = CGRect(x: 0, y: 0, width: self.buttonWidth, height: self.buttonWidth)
                btn.layer.masksToBounds = true
                btn.layer.cornerRadius = 40
                let offsetx: CGFloat = CGFloat(self.r1 * cos(self.corner1 * Float(i) + Float(M_PI_2)))
                let offsety = self.r1 * sin(self.corner1 * Float(i) + Float(M_PI_2))
                btn.center = CGPoint(x: self.circleCenter.x - offsetx, y: self.circleCenter.y - CGFloat(offsety))
                self.buttonWidth = btnWidth
                if (type == .RoundviewTypeCustom) {
                    let imageView: UIImageView = UIImageView(image: UIImage(named: images[I]))
                    imageView.contentMode = .scaleAspectFit
                    imageView.isUserInteractionEnabled = false
                    imageView.frame = CGRect(x: 25, y: 5, width: 30, height: 30)
                    btn.addSubview(imageView)
                    let label = UILabel(frame: CGRect(x: 10, y: imageView.frame.maxY + 5, width: self.buttonWidth - 20, height: 20))
                    label.text = titileArray[i]
                    label.font = UIFont.systemFont(ofSize: 12)
                    label.textColor = UIColor.black
                    label.textAlignment = .center
                    label.adjustsFontSizeToFitWidth = true
                    label.tag = I
                    btn.addSubview(label)
                } else {
                    btn.setTitle(titileArray[i], for: .normal)
                    btn.setTitleColor(UIColor.black, for: .normal)
                }
                btn.tag = I
                btn.addTarget(self, action: #selector(btnClick(btn:)), for: .touchUpInside)
                self.addSubview(btn)
                btnArray.append(btn)
            }
            let circle = CAShapeLayer()
            self.circleCenter = CGPoint(x: self.bounds.size.width/2.0, y: self.bounds.size.width/2.0)
            circle.fillColor = UIColor.clear.cgColor
            circle.strokeColor = UIColor.red.cgColor
                circle.lineWidth = 1.0
                
            circle.path = UIBezierPath(arcCenter: self.circleCenter, radius: self.cycleLineRadius, startAngle: 0.0, endAngle: CGFloat(M_PI * 2), clockwise: true).cgPath
            //注掉这行可以去除那个圆
            layer.addSublayer(circle)
        }
        
        @objc func btnClick(btn: UIButton) {
            self.isShow = true
            let num1 = btn.tag
            let name: String = nameArray?[num1] ?? ""
            let outSideName: String = outSideArray?[num1] ?? ""
            self.show()
            if let block = self.block {
                block(outSideName, name)
            }
        }
        
        @objc func changeMove(rotation: RotationGestureRecognizer) {
            if (self.btnArray!.count < 13) {
                if (self.rotationAngleInRadians == 0 && rotation.rotation > 0) {
                    return
                }
            }
            self.transform = CGAffineTransform(rotationAngle: self.rotationAngleInRadians + rotation.rotation)
            for btn in self.btnArray {
                btn.transform = CGAffineTransform(rotationAngle: -(self.rotationAngleInRadians + rotation.rotation))
            }
            for btn in self.btnArray2 {
                btn.transform = CGAffineTransform(rotationAngle: -(self.rotationAngleInRadians + rotation.rotation))
            }
            self.rotationAngleInRadians += rotation.rotation;
        }
    }
    

    RotationGestureRecognizer:

    实现拖拽旋转效果:
    import UIKit
    
    class RotationGestureRecognizer: UIGestureRecognizer {
    
        var rotation: CGFloat = 0.0
        
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
            if (event.touches(for: self)!.count > 1) {
                self.state = UIGestureRecognizer.State.failed
            }
        }
        
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
            if (self.state == UIGestureRecognizer.State.possible) {
                self.state = UIGestureRecognizer.State.began
            } else {
                self.state = UIGestureRecognizer.State.changed
            }
            let touch: UITouch? = touches.first
            let view: UIView? = self.view
            let center: CGPoint = CGPoint(x: 100, y: 100)
            let currentTouchPoint: CGPoint = (touch?.location(in: view))!
            let previousTouchPoint: CGPoint = (touch?.previousLocation(in: view))!
            let angleInRadians: CGFloat = CGFloat(atan2f(Float(currentTouchPoint.y - center.y), Float(currentTouchPoint.x - center.x)) - atan2f(Float(previousTouchPoint.y - center.y), Float(previousTouchPoint.x - center.x)))
            self.rotation = angleInRadians
        }
        
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
            if (self.state == UIGestureRecognizer.State.changed) {
                self.state = UIGestureRecognizer.State.ended
            } else {
                self.state = UIGestureRecognizer.State.failed
            }
        }
        
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
            self.state = UIGestureRecognizer.State.failed
        }
    }
    

    调用如下:

    let imageArray = ["mine_histroyIcon", "mine_histroyIcon", "mine_histroyIcon", "mine_histroyIcon", "mine_histroyIcon"]
    let titleArray = ["小锅", "拼锅", "单锅", "四宫格", "四宫格"]
    roundView = Roundview(frame: CGRect(x: 0, y: 0, width: 400, height: 400))
    //        roundView.backgroundColor = UIColor(red: 100/255.0, green: 152/255.0, blue: 251/255.0, alpha: 0.7)
    roundView.configure(type: .RoundviewTypeCustom, btnWidth: 80, adjustsFontSizesTowidth: true, masksToBounds: true, conrenrRadius: 40, images: imageArray, titileArray: titleArray, titileColor: UIColor.black, cycleLineRadius: 160.0)
    roundView.center = self.view.center
    self.view.addSubview(roundView)
    roundView.block = {(name1, name2) in
        print(name1, name2)
    }
    
    点击屏幕实现加外圈:
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let imageArray = ["mine_histroyIcon", "mine_histroyIcon", "mine_histroyIcon", "mine_histroyIcon", "mine_histroyIcon"]
        let titleArray = ["加麻", "加辣", "加番茄", "无渣", "特辣"]
        roundView.addRound2View(titileArray: titleArray, images: imageArray, conrenrRadius: 160.0, btnWidth: 80)
    }
    

    参考链接:

    iOS 圆盘旋转 ~demo:

    https://blog.csdn.net/shihuboke/article/details/83277900

    PS:算是在别人的Demo上优化修改了下实现吧,自己写真的无从下手呀,哈哈~~~代码还有点粗糙,集成项目中优化吧。。。。。。

    相关文章

      网友评论

        本文标题:Swift实现圆盘效果

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