您的位置:首页 > 移动开发 > IOS开发

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

2016-12-28 23:43 369 查看
最近由于项目需要用到星级评分、会员星级,但是在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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios 星级评分