iOS-评分星星实现小技巧

其实评分的星星实现不是很难,实现的方法很多,有用Quartz2D绘制的,有用self.backgroundColor = UIColor(patternImage: UIImage(named: "imageName")!)来实现等等,网友提供的实例也很好很多。
这里我使用的UIImageView排列来实现,只有一个file,功能简单,代码简洁,一行代码就可以得到想要的效果。可以设置星星的个数(总分),可以设置间距,可以设置大小,可以根据提供不同的图片,得到的“星星”可以不同。到这里你是不是有点好奇呢,到底有多简单。

代码文件如下:

//
//  StartView.swift
//  MeiTuan_Swift
//
//  Created by JornWu on 16/9/5.
//  Copyright © 2016年 Jorn.Wu(jorn_wza@sina.com). All rights reserved.
//

/****************************************************************************************************/
/*
**
** 这是评分的星星个数视图,直接init(...)传入所需的参数就可以生成视图
**
*/
/****************************************************************************************************/


import UIKit

class StarView: UIView {
    
    private var rate: CGFloat! //评分
    private var total: Int! //总分
    private var mStarWH: CGFloat! //星星宽高,默认20
    private var mSpace: CGFloat! //间距,默认3
    private var starImageFull: UIImage! //星星图片(填充的)(表示得到分数)
    private var starImageEmpty: UIImage! //星星图片(未填充的)(表示未得到的分数)
    
    convenience init(withRate rate: CGFloat, total: Int, starWH: CGFloat?, space: CGFloat?, starImageFull: UIImage, starImageEmpty: UIImage) {
        
        var wh: CGFloat
        var sp: CGFloat
        
        if starWH == nil{
            wh = 20 //默认 20
        }else {
            wh = starWH!
        }
        
        if space == nil{
            sp = 3 //默认 3
        }else {
            sp = space!
        }
        
        self.init(frame: CGRectMake(0, 0, (wh + sp) * CGFloat(total), wh + sp * 2))//根据星星大小来确定
        
        self.rate = rate
        self.total = total
        self.mStarWH = wh
        self.mSpace = sp
        self.starImageFull = starImageFull
        self.starImageEmpty = starImageEmpty
        
        setupView()
    }
    
    private func setupView() {
        
        ///比例
        let r = mStarWH / starImageFull.size.width ///因为星星的大小是固定的,所以要适配starView的大小
        let imgWH = starImageFull.size.width ///星星大小
        
        ///1 铺好底层
        for index in 0 ..< total {
            
            let c = index % total
            
            let starView = UIImageView(frame: CGRectMake(mSpace + (imgWH + mSpace) * CGFloat(c), mSpace, imgWH, imgWH))///space为间距
            starView.image = starImageEmpty
            starView.contentMode = UIViewContentMode.Left
            
            starView.transform = CGAffineTransformScale(starView.transform, r, r)///比例缩放
            starView.frame = CGRectMake(mSpace + (mStarWH + mSpace) * CGFloat(c), mSpace, mStarWH, mStarWH)///调整位置
            
            self.addSubview(starView)
        }
        
        ///2.1 计算最后一个星星的宽度
        let w = rate % 1 * mStarWH ///swift 浮点数可以取余
        
        if w != 0 {//w 为0时裁剪图片出错
            ///2.2 处理最后那个星星
            let fImage = UIImage.cutImage(image: starImageFull, withSize: CGSizeMake(w, mStarWH))
            
            ///3.铺好得分的星星
            let num = rate - (rate % 1) + 1
            
            for index in 0 ..< Int(num) {
                
                let c = index % total
                
                if index != Int(num - 1) {
                    
                    let starView = UIImageView(frame: CGRectMake(mSpace + (imgWH + mSpace) * CGFloat(c), mSpace, imgWH, imgWH))
                    starView.image = starImageFull
                    starView.contentMode = UIViewContentMode.Left
                    
                    starView.transform = CGAffineTransformScale(starView.transform, r, r)///比例缩放
                    starView.frame = CGRectMake(mSpace + (mStarWH + mSpace) * CGFloat(c), mSpace, mStarWH, mStarWH)
                    
                    self.addSubview(starView)
                }else {
                    let starView = UIImageView(frame: CGRectMake(mSpace + (imgWH + mSpace) * CGFloat(c), mSpace, imgWH, imgWH))
                    starView.image = fImage
                    starView.contentMode = UIViewContentMode.Left
                    
                    starView.transform = CGAffineTransformScale(starView.transform, r, r)///比例缩放
                    starView.frame = CGRectMake(mSpace + (mStarWH + mSpace) * CGFloat(c), mSpace, mStarWH, mStarWH)
                    
                    self.addSubview(starView)
                }
            }
        }else {
            ///3.铺好得分的星星
            for index in 0 ..< Int(rate) {
                
                let c = index % total
                    
                let starView = UIImageView(frame: CGRectMake(mSpace + (imgWH + mSpace) * CGFloat(c), mSpace, imgWH, imgWH))
                starView.image = starImageFull
                starView.contentMode = UIViewContentMode.Left
                
                starView.transform = CGAffineTransformScale(starView.transform, r, r)///比例缩放
                starView.frame = CGRectMake(mSpace + (mStarWH + mSpace) * CGFloat(c), mSpace, mStarWH, mStarWH)
                
                self.addSubview(starView)

            }
        }
    }

    /*
    // Only override drawRect: if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func drawRect(rect: CGRect) {
        // Drawing code
    }
    */ 

}

当然还有一个剪切图片的方法:可以放在该文件里或作为UIImageView的extention。
实现原理就是,用表示空的星星铺在底层,然后再根据所得的分,铺在上面铺表示得分的星星。整数部分不用处理,小数部分需要裁剪一下图片就好了。详细情况看代码吧。

//
//  UIImageExtension.swift
//  MeiTuan_Swift
//
//  Created by JornWu on 16/9/5.
//  Copyright © 2016年 Jorn.Wu(jorn_wza@sina.com). All rights reserved.
//

import Foundation
import UIKit

extension UIImage {
    
    static func cutImage(image img: UIImage, withSize size: CGSize) -> UIImage {
        
        var newSize: CGSize
        
        ///适应图片比例
        if (img.size.width / img.size.height) < (size.width / size.height) {//比例 高过大
            newSize = CGSizeMake(img.size.width, img.size.width * (size.height / size.width))
        }else {//比例 宽过大
            newSize = CGSizeMake(img.size.height * (size.width / size.height), img.size.height)
        }
        
        let imageRef = CGImageCreateWithImageInRect(img.CGImage, CGRectMake(0, 0, newSize.width, newSize.height))

        let newImage = UIImage(CGImage: imageRef!)

        return newImage
        
    }
    
}

然后在需要的地方添加这条代码就可以得到评分星星视图了:

let starView = StarView(withRate: 3.75, total: 5, starWH: 30, space: 3,starImageFull: UIImage(named: "icon_star_full")!, starImageEmpty: UIImage(named: "icon_star_empty")!)

starView本质是一个UIView,还可以根据starView.frame来调整位置。是不是很简单呢,当然如果你想要可以点击星星来进行评分的话,还得在这基础上进行拓展咯。喜欢给个赞吧😝😝😝。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,367评论 6 532
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,001评论 3 413
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 175,213评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,535评论 1 308
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,317评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,868评论 1 321
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,963评论 3 440
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,090评论 0 285
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,599评论 1 331
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,549评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,712评论 1 367
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,233评论 5 356
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,961评论 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,353评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,607评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,321评论 3 389
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,686评论 2 370

推荐阅读更多精彩内容