本文转载至 http://blog.csdn.net/hanhailong726188/article/details/42344131

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

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

第一步:

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

第二步:

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

第三步:

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

第四步:

在.m文件中实现评分条

具体代码如下:

RatingBar.h文件代码

//
//  RatingBar.h
//
//  Created by HailongHan on 15/1/1.
//  Copyright (c) 2015年 cubead. All rights reserved.
//

#import <UIKit/UIKit.h>

/**
 *  星级评分条代理
 */
@protocol RatingBarDelegate <NSObject>

/**
 *  评分改变
 *
 *  @param newRating 新的值
 */
- (void)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

代码中注释的很详细了,这我就不多解释了,看注释吧,真看不懂,阿门,我也救不了你!废话不多说,再贴RatingBar.m文件代码:

//  RatingBar.m
//
//  Created by HailongHan on 15/1/1.
//  Copyright (c) 2015年 cubead. All rights reserved.
//

#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;
    }
    
    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];
    
    [_s1 setFrame:CGRectMake(0,         0, width, height)];
    [_s2 setFrame:CGRectMake(width,     0, width, height)];
    [_s3 setFrame:CGRectMake(2 * width, 0, width, height)];
    [_s4 setFrame:CGRectMake(3 * width, 0, width, height)];
    [_s5 setFrame:CGRectMake(4 * width, 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];
    
    CGRect frame = [self frame];
    frame.size.width = width * 5;
    frame.size.height = height;
    [self setFrame:frame];
    
}

/**
 *  设置评分值
 *
 *  @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 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{
    [super touchesEnded:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    
    if (self.isIndicator) {
        return;
    }
    
    CGPoint point = [[touches anyObject] locationInView:self];
    int newRating = (int) (point.x / width) + 1;
    if (newRating > 5)
        return;
    
    if (point.x < 0) {
        newRating = 0;
    }
    
    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.
    
    RatingBar *ratingBar = [[RatingBar alloc] init];
    ratingBar.frame = CGRectMake(100, 100, 200, 50);
    
    [self.view addSubview:ratingBar];
    ratingBar.isIndicator = YES;//指示器,就不能滑动了,只显示评分结果
    [ratingBar setImageDeselected:@"ratingbar_unselected" halfSelected:nil fullSelected:@"ratingbar_selected" andDelegate:self];
}

好了,自定义控件就结束了,谢谢大家!

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

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

    由于项目的需要,需要设计能评分.能显示评分数据的星级评分条,但是IOS上好像没有这个控件,Android是有RatingBar这个控件的(又发现一个IOS不如Android好的),那就只能自定义了,在 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 一步一步教你如何在linux下配置apache+tomcat(转)

    一步一步教你如何在linux下配置apache+tomcat   一.安装前准备. 1.   所有组件都安装到/usr/local/e789目录下 2.   解压缩命令:tar —vxzf 文件名(. ...

随机推荐

  1. Android开发中遇到的问题(五)——Eclipse导入Android项目出现"Invalid project description overlaps the location of another project"错误的解决办法

    一.错误描述 使用如下的命令手动创建一个Android项目 android create project -n LinearLayoutTest -t -p E:/Android/workspace/ ...

  2. Unity中巧用协程和游戏对象的生命周期处理游戏重启的问题

    主要用到协程(Coroutines)和游戏对象的生命周期(GameObject Lifecycle)基础知识,巧妙解决了游戏重启的问题. 关于协程,这里有篇文章我觉得写的非常好,理解起来也很容易.推荐 ...

  3. Markdown 语法手册 - 完整版(下)

    6. 引用 语法说明: 引用需要在被引用的文本前加上>符号. 代码: > 这是一个有两段文字的引用, > 无意义的占行文字1. > 无意义的占行文字2. > > 无 ...

  4. Spring Boot异常处理

    一.默认映射 我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局 ...

  5. python3简单使用requests 用户代理,cookie池

    官方文档:http://docs.python-requests.org/en/master/ 参考文档:http://www.cnblogs.com/zhaof/p/6915127.html#und ...

  6. 在Linux平台上搭建EasyDarwin,编译代码并简单部署

    測试环境: Ubuntu gcc / g++ 从https://github.com/EasyDarwin/EasyDarwin下载代码 1.编译 第一步:进入源码文件夹下 cd ./EasyDarw ...

  7. SoapUI Pro Project Solution Collection –Easy develop Groovy Script to improve SoapUI ability

    As you know the groovy script and java script language is the soapui supported .but unfortunately So ...

  8. 一篇文章让你读懂iOS和Android的历史起源

    智能手机虽说是移动电话,但我们完全可以将其作为小型化的电脑来思考.这样一来也能够显示出智能手机OS的高性能.我们首先一起来回顾下智能手机OS的历史. OS的黎明期 其实在很早之前就已经有这样的想法,即 ...

  9. 11G新特性 -- 收缩临时表空间

    当大任务执行完毕,并不会立即释放临时表空间.有时候通过删除然后重建临时表空间的速度可能更快.不过对于在线系统可能不会那么容易删除重建,所以11g中可以在线收缩临时表空间或单个临时数据文件. 收缩临时表 ...

  10. 11G新特性 -- Statistics Preferences

    Statistics Preferences新特性可以实现对指定对象进行信息收集. 可以在table.schema.database.global级别设置statistics preference. ...