由于项目的需要,需要设计能评分、能显示评分数据的星级评分条,但是IOS上好像没有这个控件,Android是有RatingBar这个控件的(又发现一个IOS不如Android好的),那就只能自定义了,在网上也找了相关的例子,发现都是很老的版本了,非ARC版本的,而且不能评分成0分,还没有indicator效果,于是我自己重新写了一个控件,命名为RatingBar

先上一张我们做之后的效果图:

第一步:

写一个继承自UIView的RatingBar子控件

第二步:

声明一个RatingBar修改评分的代理,就是评分修改后把最新的评分告诉对方

第三步:

在.h文件中声明一些要暴漏给别人调用的方法

第四步:

在.m文件中实现评分条

具体代码如下:

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;

@end

.m文件

#import "RatingBar.h"

@interface RatingBar (){
    float starRating;
    float lastRating;
    
    float height;
    float width;
    
    UIImage *unSelectedImage;
    UIImage *halfSelectedImage;
    UIImage *fullSelectedImage;
}

@property (nonatomic,strong) UIImageView *s1;
@property (nonatomic,strong) UIImageView *s2;
@property (nonatomic,strong) UIImageView *s3;
@property (nonatomic,strong) UIImageView *s4;
@property (nonatomic,strong) UIImageView *s5;

@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 * 5;
    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;
    
    _s1 = [[UIImageView alloc] initWithImage:unSelectedImage];
    _s2 = [[UIImageView alloc] initWithImage:unSelectedImage];
    _s3 = [[UIImageView alloc] initWithImage:unSelectedImage];
    _s4 = [[UIImageView alloc] initWithImage:unSelectedImage];
    _s5 = [[UIImageView alloc] initWithImage:unSelectedImage];
    
    
    //星星图片之间的间距
    CGFloat space = (CGFloat)(viewWidth - width*5)/6;
    
    CGFloat startX = space;
    [_s1 setFrame:CGRectMake(startX,         0, width, height)];
    startX += width + space;
    [_s2 setFrame:CGRectMake(startX,     0, width, height)];
    startX += width + space;
    [_s3 setFrame:CGRectMake(startX, 0, width, height)];
    startX += width + space;
    [_s4 setFrame:CGRectMake(startX, 0, width, height)];
    startX += width + space;
    [_s5 setFrame:CGRectMake(startX, 0, width, height)];
    
    [_s1 setUserInteractionEnabled:NO];
    [_s2 setUserInteractionEnabled:NO];
    [_s3 setUserInteractionEnabled:NO];
    [_s4 setUserInteractionEnabled:NO];
    [_s5 setUserInteractionEnabled:NO];
    
    [self addSubview:_s1];
    [self addSubview:_s2];
    [self addSubview:_s3];
    [self addSubview:_s4];
    [self addSubview:_s5];
    
}

/**
 *  设置评分值
 *
 *  @param rating 评分值
 */
-(void)displayRating:(float)rating{
    
    [_s1 setImage:unSelectedImage];
    [_s2 setImage:unSelectedImage];
    [_s3 setImage:unSelectedImage];
    [_s4 setImage:unSelectedImage];
    [_s5 setImage:unSelectedImage];
    
    if (rating >= 0.5) {
        [_s1 setImage:halfSelectedImage];
    }
    if (rating >= 1) {
        [_s1 setImage:fullSelectedImage];
    }
    if (rating >= 1.5) {
        [_s2 setImage:halfSelectedImage];
    }
    if (rating >= 2) {
        [_s2 setImage:fullSelectedImage];
    }
    if (rating >= 2.5) {
        [_s3 setImage:halfSelectedImage];
    }
    if (rating >= 3) {
        [_s3 setImage:fullSelectedImage];
    }
    if (rating >= 3.5) {
        [_s4 setImage:halfSelectedImage];
    }
    if (rating >= 4) {
        [_s4 setImage:fullSelectedImage];
    }
    if (rating >= 4.5) {
        [_s5 setImage:halfSelectedImage];
    }
    if (rating >= 5) {
        [_s5 setImage:fullSelectedImage];
    }
    
    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*5)/6;
    
    float newRating = 0;
    
    if (point.x >= 0 && point.x <= self.frame.size.width) {
        
        if (point.x <= space+width*0.5f) {
            newRating = 0.5;
        }else if (point.x < space*2+width){
            newRating = 1.0;
        }else if (point.x < space*2+width*1.5){
            newRating = 1.5;
        }else if (point.x <= 3*space+2*width){
            newRating = 2.0;
        }else if (point.x <= 3*space+2.5*width){
            newRating = 2.5;
        }else if (point.x <= 4*space+3*width){
            newRating = 3.0;
        }else if (point.x <= 4*space+3.5*width){
            newRating = 3.5;
        }else if (point.x <= 5*space+4*width){
            newRating = 4.0;
        }else if (point.x <=5*space+4.5*width){
            newRating = 4.5;
        }else {
            newRating = 5.0;
        }
        
    }
    
    if (newRating != lastRating){
        [self displayRating:newRating];
    }
}

@end

调用:

#import "ViewController.h"
#import "RatingBar.h"

@interface ViewController ()<RatingBarDelegate>

@property (nonatomic,strong) UILabel *mLabel;

@property (nonatomic,strong) RatingBar *ratingBar1;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self setupViews];
}

#pragma mark - 初始化view
- (void)setupViews{
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    //RatingBar1
    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 setImageDeselected:@"iconfont-xingunselected" halfSelected:@"iconfont-banxing" fullSelected:@"iconfont-xing" andDelegate:self];
    
    //RatingBar2
    CGFloat width2 = 250;
    CGFloat x2 = (self.view.bounds.size.width - width2)*0.5;
    self.ratingBar2 = [[RatingBar alloc] initWithFrame:CGRectMake(x2, 200, width2, 50)];
    self.ratingBar2.isIndicator = NO;
    [self.ratingBar2 setImageDeselected:@"iconfont-xingunselected" halfSelected:@"iconfont-banxing" fullSelected:@"iconfont-xing" andDelegate:self];
    [self.view addSubview:self.ratingBar2];
    
    //RatingBar3
    CGFloat width3 = 300;
    CGFloat x3 = (self.view.bounds.size.width - width3)*0.5;
    self.ratingBar3 = [[RatingBar alloc] initWithFrame:CGRectMake(x3, 300, width3, 50)];
    self.ratingBar3.isIndicator = NO;
    [self.ratingBar3 setImageDeselected:@"iconfont-xingunselected" halfSelected:@"iconfont-banxing" fullSelected:@"iconfont-xing" andDelegate:self];
    [self.view addSubview:self.ratingBar3];
    
    //显示结果的UILabel
    CGFloat labelX = (self.view.bounds.size.width - 400)*0.5f;
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(labelX, 400, 400, 50)];
    label.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:label];
    
    self.mLabel = label;
}

#pragma mark - RatingBar delegate
-(void)ratingBar:(RatingBar *)ratingBar ratingChanged:(float)newRating{
    if (self.ratingBar1 == ratingBar) {
        self.mLabel.text = [NSString stringWithFormat:@"第一个评分条的当前结果为:%.1f",newRating];
        
    }else if (self.ratingBar2 == ratingBar){
        self.mLabel.text = [NSString stringWithFormat:@"第二个评分条的当前结果为:%.1f",newRating];
        
    }else if (self.ratingBar3 == ratingBar){
        self.mLabel.text = [NSString stringWithFormat:@"第三个评分条的当前结果为:%.1f",newRating];
        
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

IOS-一步一步教你自定义评分星级条RatingBar ——转载的的更多相关文章

  1. IOS-一步一步教你自定义评分星级条RatingBar

    本文转载至 http://blog.csdn.net/hanhailong726188/article/details/42344131 由于项目的需要,需要设计能评分.能显示评分数据的星级评分条,但 ...

  2. 教你上传本地代码到github转载

    原创 2015年07月03日 10:47:13 标签: 上传代码github   转载请标明出处: http://blog.csdn.net/hanhailong726188/article/deta ...

  3. 一步一步教你实现iOS音频频谱动画(二)

    如果你想先看看最终效果再决定看不看文章 -> bilibili 示例代码下载 第一篇:一步一步教你实现iOS音频频谱动画(一) 本文是系列文章中的第二篇,上篇讲述了音频播放和频谱数据计算,本篇讲 ...

  4. 一步一步教你实现iOS音频频谱动画(一)

    如果你想先看看最终效果再决定看不看文章 -> bilibili 示例代码下载 第二篇:一步一步教你实现iOS音频频谱动画(二) 基于篇幅考虑,本次教程分为两篇文章,本篇文章主要讲述音频播放和频谱 ...

  5. 一步一步教你将普通的wifi路由器变为智能广告路由器

    一步一步教你将普通的wifi路由器变为智能广告路由器 相信大家对WiFi智能广告路由器已经不再陌生了,现在很多公共WiFi上网,都需要登录并且验证,这也就是WiFi广告路由器的最重要的功能.大致就是下 ...

  6. 通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权

    Oauth2授权,熟悉微信开发的同学对这个东西应该不陌生吧.当我们的应用系统需要集成第三方授权时一般都会做oauth集成,今天就来看看在Dapr的语境下我们如何仅通过配置无需修改应用程序的方式让第三方 ...

  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定

    如果说Actor是dapr有状态服务的内部体现的话,那绑定应该是dapr对serverless这部分的体现了.我们可以通过绑定极大的扩展应用的能力,甚至未来会成为serverless的基础.最开始接触 ...

  8. 通过Dapr实现一个简单的基于.net的微服务电商系统(十一)——一步一步教你如何撸Dapr之自动扩/缩容

    上一篇我们讲到了dapr提供的bindings,通过绑定可以让我们的程序轻装上阵,在极端情况下几乎不需要集成任何sdk,仅需要通过httpclient+text.json即可完成对外部组件的调用,这样 ...

  9. 一步一步教你编写与搭建自动化测试框架——python篇

    [本文出自天外归云的博客园] 这两天用python写了一个自动化测试框架,取名为Auty.准备用来做Web方面的接口测试,以下为Auty框架一步一步的搭建过程——

随机推荐

  1. (转)Block的使用

    转:http://my.oschina.net/leejan97/blog/268536 本文翻译自苹果的文档,有删减,也有添加自己的理解部分. 如果有Block语法不懂的,可以参考fuckingbl ...

  2. Effective Java 32 Use EnumSet instead of bit fields

    Bit fields is used for passing around sets of constants. Such as // Bit field enumeration constants ...

  3. MySQL中的FEDERATED引擎

    首先说明>     FEDERATED存储引擎访问在远程数据库的表中的数据,而不是本地的表.这个特性给某些开发应用带来了便利,你可以直接在本地构建一个federated表来连接远程数据表,配置好 ...

  4. 【windows环境下】RabbitMq的安装和监控插件安装

    RabbitMq的安装: RabbitMQ是基于Erlang的,所以必须先配置Erlang环境. 下载Erlang,地址:http://www.erlang.org/download/otp_win3 ...

  5. Moodle插件之Filters(过滤器)

    Moodle插件之Filters(过滤器) 过滤器是一种在输出之前自动转换内容的方法. 目的: 创建名为helloworld的过滤器,实现将预输出的“world”字符串替换成“hello world” ...

  6. 在VMware Workstation11虚拟机上安装黑苹果

    图文详解如何在VMware Workstation11虚拟机上安装黑苹果Mac OS X 10.10系统-网络教程与技术 -亦是美网络 http://www.yishimei.cn/network/5 ...

  7. js动态切换图片

    <script language =javascript > $(function () { initAds(); }); function initAds() { var curInde ...

  8. Mathout

    1. 用Maven搭建Mahout的开发环境,并完成PPT 26页,最简单的例子.要求有过程说明和截图. 2. 用案例的数据集,基于Mahout,任选一种算法,对任意一个女性用户进行协同过滤推荐,并解 ...

  9. uva 11054 wine trading in gergovia (归纳【好吧这是我自己起的名字】)——yhx

    As you may know from the comic \Asterix and the Chieftain's Shield", Gergovia consists of one s ...

  10. Stanford机器学习笔记-1.线性回归

    Content: 1. Linear Regression 1.1 Linear Regression with one variable 1.1.1 Gradient descent algorit ...