打造通用的自定义评分星级RatingBar

来源:互联网 发布:snapgene mac 编辑:程序博客网 时间:2024/05/16 06:38

最近由于项目需要用到星级评分、会员星级,但是在IOS中并没有现成的控件,然后就在群里面跟朋友抱怨了几句,在Android要实现这个功能只需要拖个控件,几行代码就搞定了。当然,这也并不是想要表明IOS、Android哪个更好。

于是乎,就通过度娘看了一些有关的文章,都发现不适合我项目的需求,比如说有些不能点击,有些不能滑动评分,有些不能评分,有些不能设置指定的星星数。最后找到一个比较与我的项目需求接近的IOS-一步一步教你自定义评分星级条RatingBar,于是在它的基础上进行了扩展,添加了可以指定星星数量的功能,在此表示感谢这位博主,好了无图就无真相,先上图看看真相。
这里写图片描述

具体的代码也不多,代码中都基本有注释:
RatingBar.h文件代码

#import <UIKit/UIKit.h>@class RatingBar;/** *  星级评分条代理 */@protocol RatingBarDelegate <NSObject>/** *  评分改变 * *  @param ratingBar 评分控件 *  @param newRating 评分值 */- (void)ratingBar:(RatingBar *)ratingBar ratingChanged:(float)newRating;@end@interface RatingBar : UIView/** *  初始化设置未选中图片、半选中图片、全选中图片,以及评分值改变的代理(可以用 *  Block)实现 * *  @param deselectedName   未选中图片名称 *  @param halfSelectedName 半选中图片名称 *  @param fullSelectedName 全选中图片名称 *  @param delegate          代理 */- (void)setImageDeselected:(NSString *)deselectedName halfSelected:(NSString *)halfSelectedName fullSelected:(NSString *)fullSelectedName andDelegate:(id<RatingBarDelegate>)delegate;/** *  设置评分值 * *  @param rating 评分值 */- (void)displayRating:(float)rating;/** *  获取当前的评分值 * *  @return 评分值 */- (float)rating;/** *  是否是指示器,如果是指示器,就不能滑动了,只显示结果,不是指示器的话就能滑动修改值 *  默认为NO */@property (nonatomic,assign) BOOL isIndicator;/** *  星星数量,如果没有设置星星的数量,则默认为5颗星星 * */@property (nonatomic, assign) int starsNum;@end

接着自然是RatingBar.m文件的代码嘞:

#import "RatingBar.h"@interface RatingBar (){    float starRating;    float lastRating;    float height;    float width;    UIImage *unSelectedImage;    UIImage *halfSelectedImage;    UIImage *fullSelectedImage;    NSMutableArray *starsArray; // 保存生成的每一个星星}@property (nonatomic, strong) UIImageView *stars;@property (nonatomic,weak) id<RatingBarDelegate> delegate;@end@implementation RatingBar/** *  初始化设置未选中图片、半选中图片、全选中图片,以及评分值改变的代理(可以用 *  Block)实现 * *  @param deselectedName   未选中图片名称 *  @param halfSelectedName 半选中图片名称 *  @param fullSelectedName 全选中图片名称 *  @param delegate          代理 */-(void)setImageDeselected:(NSString *)deselectedName halfSelected:(NSString *)halfSelectedName fullSelected:(NSString *)fullSelectedName andDelegate:(id<RatingBarDelegate>)delegate{    self.delegate = delegate;    unSelectedImage = [UIImage imageNamed:deselectedName];    halfSelectedImage = halfSelectedName == nil ? unSelectedImage : [UIImage imageNamed:halfSelectedName];    fullSelectedImage = [UIImage imageNamed:fullSelectedName];    height = 0.0,width = 0.0;    if (height < [fullSelectedImage size].height) {        height = [fullSelectedImage size].height;    }    if (height < [halfSelectedImage size].height) {        height = [halfSelectedImage size].height;    }    if (height < [unSelectedImage size].height) {        height = [unSelectedImage size].height;    }    if (width < [fullSelectedImage size].width) {        width = [fullSelectedImage size].width;    }    if (width < [halfSelectedImage size].width) {        width = [halfSelectedImage size].width;    }    if (width < [unSelectedImage size].width) {        width = [unSelectedImage size].width;    }    //控件宽度适配    CGRect frame = [self frame];    CGFloat viewWidth = width * _starsNum;    if (frame.size.width > viewWidth) {        viewWidth = frame.size.width;    }    frame.size.width = viewWidth;    frame.size.height = height;    [self setFrame:frame];    starRating = 0.0;    lastRating = 0.0;    // 如果没有设置星星的数量,则默认为5    if(_starsNum == 0){        _starsNum = 5;    }    starsArray = [[NSMutableArray alloc]init];    for(int i = 0; i < _starsNum; i++){        _stars = [[UIImageView alloc] initWithImage:unSelectedImage];        //星星图片之间的间距        CGFloat space = (CGFloat)(viewWidth - width * _starsNum)/(_starsNum + 1);        CGFloat startX = space;        [_stars setFrame:CGRectMake(startX + i * (width + space), 0, width, height)];        [_stars setUserInteractionEnabled:NO];        [starsArray addObject:_stars];        [self addSubview:_stars];    }}/** *  设置评分值 * *  @param rating 评分值 */-(void)displayRating:(float)rating{    for(int i = 0; i < _starsNum; i++){        [starsArray[i] setImage:unSelectedImage];    }    // 根据分数来显示不同的图片    int score = floor(rating);    for(int k = 0; k < score; k++){        [starsArray[k] setImage:fullSelectedImage];    }    if(rating > score){        [starsArray[score] setImage:halfSelectedImage];    }    starRating = rating;    lastRating = rating;    [_delegate ratingBar:self ratingChanged:rating];}/** *  获取当前的评分值 * *  @return 评分值 */-(float)rating{    return starRating;}-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{    [super touchesBegan:touches withEvent:event];}-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{    [self touchesRating:touches];}-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{    [self touchesRating:touches];}//触发- (void)touchesRating:(NSSet *)touches{    if (self.isIndicator) {        return;    }    CGPoint point = [[touches anyObject] locationInView:self];    //星星图片之间的间距    CGFloat space = (CGFloat)(self.frame.size.width - width * _starsNum)/(_starsNum + 1);    float newRating = 0;    // 根据点击的x轴的位置来得到对应的分数    if (point.x >= 0 && point.x <= self.frame.size.width) {        int i = 0;        int starsMax = 100;        for(; i < starsMax; i++){            int num = space * ceil((i + 1) / 2.0) + width * (0.5 * i);            if(point.x <= num){                newRating = 0.5 * i;                break;            }        }            }    if (newRating != lastRating){        [self displayRating:newRating];    }}@end

到这里星级评分的功能基本就实现了,将这两个.h和.m文件放到项目中就可以使用了,在ViewController.m文件中调用代码如下:

- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    CGFloat width = 200;    CGFloat x = (self.view.bounds.size.width - width)*0.5;    self.ratingBar1 = [[RatingBar alloc] initWithFrame:CGRectMake(x, 100, width, 50)];    //添加到view中    [self.view addSubview:self.ratingBar1];    //是否是指示器    self.ratingBar1.isIndicator = NO;    // 设置星星的数量    self.ratingBar1.starsNum = 4;    [self.ratingBar1 setImageDeselected:@"iconfont-xingunselected" halfSelected:@"iconfont-banxing" fullSelected:@"iconfont-xing" andDelegate:self];}

最后附上源码地址:https://github.com/chw2317/RatingBar

0 0
原创粉丝点击