由于项目的需要,需要设计能评分、能显示评分数据的星级评分条,但是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. quote、cite、refer的区别

    quote指“直引”,直接引用原文,不做丝毫修改. cite指“间引”,引用时不需要相同的词. refer指消化原来的思想,完全不抄.

  2. 项目管理工具之Git使用说明

    1.下载Git客户端工具 http://msysgit.github.com/ 2.安装msysgit 下一步 同意GNU协议 选择安装位置 选择TrueType  Front,下一步 不创建启动文件 ...

  3. 问题解决——multimap中统计key的种类

    ================声明================= 本文原创,转载请注明出处和作者,并保持文章的完整性. 本文链接:http://www.cnblogs.com/wlsandwho ...

  4. linux 程序管理

    在linux下做开发,经常要用到一些管理程序的命令,如查看进程,查看内存等情况.看网络情况.如下的笔记是看书时记下一些简单常用的命令. 1)top [root@005 fsh]#top[-d数字]|t ...

  5. 【开学季】自学嵌入式开发|四核开发板|4412开发板|ARM+Android+linux技术

    淘宝店铺:迅为开发板http://arm-board.taobao.com 网站:http://www.topeetboard.com QQ咨询:2551456065 电话咨询:010-5895758 ...

  6. Regarding learning

    when you learn something, just like learn computer language. if you just learn some basic usage, not ...

  7. xml in hadoop ETL with pig summary

    项目中需要把source为xml的文件通过flume放置到hdfs,然后通过MR导入到vertica中去,我之前做过简单的 尝试,是通过pig的piggybank的xmlloader然后Regex_e ...

  8. ETL from hadoop to vertica

    根据项目需要,我做了一个POC(proof of concept),XML TXT的数据从HADOOP 引入到VERTICA. 我采用的方案是pig,具体信息可以参加vertica官方的文档. Acc ...

  9. Spring中AOP原理,源码学习笔记

    一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...

  10. FPGA 设计技巧

    1.  资源共享的应用限制在同一个module里 这样 综合工具才能最大限度地发挥其资源共 享综合作用 2.  尽可能将Critical path上所有相关逻辑放在同一个module里 这样 综合工具 ...