UI随便

Swift实现圆盘效果

2020-07-03  本文已影响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上优化修改了下实现吧,自己写真的无从下手呀,哈哈~~~代码还有点粗糙,集成项目中优化吧。。。。。。

上一篇 下一篇

猜你喜欢

热点阅读