Swift 星星評價控制元件

Brocadecarp發表於2019-04-03

空閒時間裡,做了一個星星評價的控制元件,如下:

StartRateControl.gif
好了,廢話不多說,先說思路吧~首先,要先建立層View,一層裝未選中的星星,一層裝選中的星星,如圖:
Swift 星星評價控制元件
我的思路就是,在兩層View上,分別放上選中星星的圖片和未選中星星的圖片,然後再獲取手勢的位置設定選中星星圖層的寬度,分為兩個思路,一個是滑動,一個則是點選,下面是滑動評分的程式碼,根據滑動手勢獲取位置計算出評分

//滑動評分
    @objc func starPan(_ recognizer:UIPanGestureRecognizer) -> () {
        var OffX:CGFloat = 0
        if recognizer.state == .began{
            OffX = recognizer.location(in: self).x
        }else if recognizer.state == .changed{
            OffX += recognizer.location(in: self).x
        }else{
            return
        }
        // 最低一顆星星
        if OffX < 0 {
            OffX = 1
        }
        self.score = Float(OffX) / Float(self.bounds.width) * Float(self.count)
        showStarRate()
        backSorce()
    }
複製程式碼

下面是點選評分的程式碼,根據點選手勢獲取位置計算出評分

//點選評分
    @objc func starTap(_ recognizer:UIPanGestureRecognizer) -> () {
        if !self.allowTap {
            return
        }
        let OffX = recognizer.location(in: self).x
        self.score = Float(OffX) / Float(self.bounds.width) * Float(self.count)
        showStarRate()
        backSorce()
    }
複製程式碼

然後根據手勢計算的評分來重新整理UI介面,在顯示評分這裡,有兩個思路,一個是支援非整星的評分,一個是隻支援整星的評分

 //顯示評分
    fileprivate func showStarRate(){
        let  duration = (usePanAnimation && !firstInit) ? 0.1 : 0.0
        UIView.animate(withDuration: duration, animations: {
            if self.allowUnderCompleteStar{//支援非整星評分
                self.starForegroundView.frame = CGRect(x: 0,y: 0,width: self.bounds.width / CGFloat(self.count) * CGFloat(self.score),height: self.bounds.height)
            }else{//只支援整星評分
                self.starForegroundView.frame = CGRect(x: 0,y: 0,width: self.bounds.width / CGFloat(self.count) * CGFloat(ceilf(self.score)),height: self.bounds.height)
            }
        })
    }
複製程式碼

核心程式碼基本就在這三個方法裡面,向外界傳遞評價分數我是用的 block 傳的,根據個人喜好,也可以用代理的方式提供給外界,這裡就不放程式碼了。 在外面呼叫星星評價控制元件也非常簡單,下面上個呼叫的方法

// 評分星星
    fileprivate lazy var startStateView: THStartRateView = {
        let frame = CGRect(x: 20, y: 200, width: 160, height:27)
        let startView = THStartRateView.init(frame: frame, starCount: 5, score: 5, foreImageName: "bigbig", interval: 5)
        startView.score = 5
        startView.allowTap = true
        startView.allowUserPan = true
        startView.isUserInteractionEnabled = true
        return startView
    }()
複製程式碼

相關文章