iOS - Label 数字动态变化
1、数字动态变化
- 具体实现代码见 GitHub 源码 QExtension 
- QCountingLabel.h - /// 文本数字变化方式枚举
 typedef NS_ENUM(NSUInteger, QCountingMethod) { QCountingMethodEaseInOut, // 开始结束慢,中间快
 QCountingMethodEaseIn, // 开始慢,结束快
 QCountingMethodEaseOut, // 开始快,结束慢
 QCountingMethodLinear // 匀速
 }; @interface QCountingLabel : UILabel /// 文本数字样式,默认为 @"%f"
 @property (nonatomic, strong) NSString *format; /// 文本数字分隔符样式,例如 @"###,##0.00"
 @property (nonatomic, strong) NSString *positiveFormat; /// 文本数字变化方式,默认为 EaseInOut
 @property (nonatomic, assign) QCountingMethod method; /// 文本数字变化时间,默认为 2.0
 @property (nonatomic, assign) NSTimeInterval animationDuration; /// 文本数字样式 Block
 @property (nonatomic, copy) NSString *(^formatBlock)(CGFloat); /// 富文本数字样式 Block
 @property (nonatomic, copy) NSAttributedString *(^attributedFormatBlock)(CGFloat); /// 文本数字变化完成回调 Block
 @property (nonatomic, copy) void (^completionBlock)(); /**
 * 文本数字在指定时间内从起始值变化到结束值
 *
 * @param frame 控件的 frame
 * @param format 文本数字样式,默认为 @"%f"
 * @param positiveFormat 文本数字分隔符样式
 * @param method 文本数字变化方式,默认为 EaseInOut
 * @param startValue 起始值
 * @param endValue 结束值
 * @param duration 变化时间
 * @param completion 完成回调
 *
 * @return QCountingLabel 对象
 */
 + (instancetype)q_countingLabelWithFrame:(CGRect)frame
 format:(NSString *)format
 positiveFormat:(nullable NSString *)positiveFormat
 method:(QCountingMethod)method
 fromValue:(CGFloat)startValue
 toValue:(CGFloat)endValue
 withDuration:(NSTimeInterval)duration
 completion:(void (^)())completion; /**
 * 文本数字从起始值变化到结束值
 *
 * <p> 默认变化时间 2.0 秒 <p>
 *
 * @param startValue 起始值
 * @param endValue 结束值
 *
 * @return nil
 */
 - (void)q_countFromValue:(CGFloat)startValue toValue:(CGFloat)endValue; /**
 * 文本数字在指定时间内从起始值变化到结束值
 *
 * @param startValue 起始值
 * @param endValue 结束值
 * @param duration 变化时间
 *
 * @return nil
 */
 - (void)q_countFromValue:(CGFloat)startValue toValue:(CGFloat)endValue withDuration:(NSTimeInterval)duration; /**
 * 文本数字从当前值变化到结束值
 *
 * <p> 默认变化时间 2.0 秒 <p>
 *
 * @param endValue 结束值
 *
 * @return nil
 */
 - (void)q_countFromCurrentValueToValue:(CGFloat)endValue; /**
 * 文本数字在指定时间内从当前值变化到结束值
 *
 * @param endValue 结束值
 * @param duration 变化时间
 *
 * @return nil
 */
 - (void)q_countFromCurrentValueToValue:(CGFloat)endValue withDuration:(NSTimeInterval)duration; /**
 * 文本数字从 0 变化到结束值
 *
 * <p> 默认变化时间 2.0 秒 <p>
 *
 * @param endValue 结束值
 *
 * @return nil
 */
 - (void)q_countFromZeroToValue:(CGFloat)endValue; /**
 * 文本数字在指定时间内从 0 变化到结束值
 *
 * @param endValue 结束值
 * @param duration 变化时间
 *
 * @return nil
 */
 - (void)q_countFromZeroToValue:(CGFloat)endValue withDuration:(NSTimeInterval)duration; @end
 
- QCountingLabel.m - #ifndef kQLabelCounterRate
 #define kQLabelCounterRate 3.0
 #endif NS_ASSUME_NONNULL_BEGIN @interface QCountingLabel () @property (nonatomic, assign) CGFloat startingValue;
 @property (nonatomic, assign) CGFloat destinationValue;
 @property (nonatomic, assign) NSTimeInterval progress;
 @property (nonatomic, assign) NSTimeInterval lastUpdate;
 @property (nonatomic, assign) NSTimeInterval totalTime;
 @property (nonatomic, assign) CGFloat easingRate; @property (nonatomic, strong, nullable) CADisplayLink *timer; @end @implementation QCountingLabel #pragma mark - 文本数字变化方法 /// 创建 QCountingLabel 对象
 + (instancetype)q_countingLabelWithFrame:(CGRect)frame
 format:(NSString *)format
 positiveFormat:(nullable NSString *)positiveFormat
 method:(QCountingMethod)method
 fromValue:(CGFloat)startValue
 toValue:(CGFloat)endValue
 withDuration:(NSTimeInterval)duration
 completion:(void (^)())completion { QCountingLabel *label = [[self alloc] initWithFrame:frame]; label.format = format;
 label.positiveFormat = positiveFormat;
 label.method = method;
 label.completionBlock = completion;
 [label q_countFromValue:startValue toValue:endValue withDuration:duration]; return label;
 } /// 文本数字从起始值变化到结束值
 - (void)q_countFromValue:(CGFloat)startValue toValue:(CGFloat)endValue { if (self.animationDuration == 0.0f) {
 self.animationDuration = 2.0f;
 } [self q_countFromValue:startValue toValue:endValue withDuration:self.animationDuration];
 } /// 文本数字在指定时间内从起始值变化到结束值
 - (void)q_countFromValue:(CGFloat)startValue toValue:(CGFloat)endValue withDuration:(NSTimeInterval)duration { self.startingValue = startValue;
 self.destinationValue = endValue; // remove any (possible) old timers
 [self.timer invalidate];
 self.timer = nil; if (duration == 0.0) { // No animation
 [self q_setTextValue:endValue]; if (self.completionBlock) {
 self.completionBlock();
 } return;
 } self.easingRate = 3.0f;
 self.progress = 0;
 self.totalTime = duration;
 self.lastUpdate = [NSDate timeIntervalSinceReferenceDate]; if (self.format == nil) {
 self.format = @"%f";
 } CADisplayLink *timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(q_timerUpdate:)];
 timer.frameInterval = 2;
 [timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
 [timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:UITrackingRunLoopMode];
 self.timer = timer;
 } /// 文本数字从当前值变化到结束值
 - (void)q_countFromCurrentValueToValue:(CGFloat)endValue { [self q_countFromValue:[self q_getCurrentValue] toValue:endValue];
 } /// 文本数字在指定时间内从当前值变化到结束值
 - (void)q_countFromCurrentValueToValue:(CGFloat)endValue withDuration:(NSTimeInterval)duration { [self q_countFromValue:[self q_getCurrentValue] toValue:endValue withDuration:duration];
 } /// 文本数字从 0 变化到结束值
 - (void)q_countFromZeroToValue:(CGFloat)endValue { [self q_countFromValue:0.0f toValue:endValue];
 } /// 文本数字在指定时间内从 0 变化到结束值
 - (void)q_countFromZeroToValue:(CGFloat)endValue withDuration:(NSTimeInterval)duration { [self q_countFromValue:0.0f toValue:endValue withDuration:duration];
 } /// format setter
 - (void)setFormat:(NSString *)format { _format = format; // update label with new format
 [self q_setTextValue:self.q_getCurrentValue];
 } #pragma mark - 工具方法 /// 定时器定时响应事件处理
 - (void)q_timerUpdate:(NSTimer *)timer { // update progress
 NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
 self.progress += now - self.lastUpdate;
 self.lastUpdate = now; if (self.progress >= self.totalTime) {
 [self.timer invalidate];
 self.timer = nil;
 self.progress = self.totalTime;
 } [self q_setTextValue:[self q_getCurrentValue]]; if (self.progress == self.totalTime) {
 if (self.completionBlock) {
 self.completionBlock();
 }
 }
 } /// 设置数值
 - (void)q_setTextValue:(CGFloat)value { if (self.attributedFormatBlock != nil) { self.attributedText = self.attributedFormatBlock(value); } else if (self.formatBlock != nil) { self.text = self.formatBlock(value); } else { // check if counting with ints - cast to int
 if ([self.format rangeOfString:@"%(.*)d" options:NSRegularExpressionSearch].location != NSNotFound ||
 [self.format rangeOfString:@"%(.*)i"].location != NSNotFound) { // 整型样式
 self.text = [NSString stringWithFormat:self.format, (int)value]; } else if (self.positiveFormat.length > 0) { // 带千分位分隔符的浮点型样式
 NSString *str = [NSString stringWithFormat:self.format, value]; NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
 formatter.numberStyle = NSNumberFormatterDecimalStyle;
 [formatter setPositiveFormat:self.positiveFormat];
 NSString *formatterString = [formatter stringFromNumber:[NSNumber numberWithFloat:[str floatValue]]]; self.text = formatterString; } else { // 普通浮点型样式
 self.text = [NSString stringWithFormat:self.format, value];
 }
 }
 } /// 获取当前值
 - (CGFloat)q_getCurrentValue { if (self.progress >= self.totalTime) {
 return self.destinationValue;
 } CGFloat percent = self.progress / self.totalTime;
 CGFloat updateVal = [self update:percent]; return self.startingValue + (updateVal * (self.destinationValue - self.startingValue));
 } /// 更新数值
 - (CGFloat)update:(CGFloat)t { switch (self.method) { case 0: {
 int sign = 1;
 int r = (int)kQLabelCounterRate; if (r % 2 == 0) {
 sign = -1;
 } t *= 2; if (t < 1) {
 return 0.5f * powf(t, kQLabelCounterRate);
 } else {
 return sign * 0.5f * (powf(t - 2, kQLabelCounterRate) + sign * 2);
 } break;
 } case 1: {
 return powf(t, kQLabelCounterRate); break;
 } case 2: {
 return 1.0 - powf((1.0 - t), kQLabelCounterRate); break;
 } case 3: {
 return t; break;
 } default:
 return t;
 }
 } @end
 
- 使用 - 1、初始化 - QCountingLabel 继承自 UILabel, 初始化和 UILabel 一样 - // 创建 QCountingLabel 对象
 QCountingLabel *countingLabel = [[QCountingLabel alloc] initWithFrame:CGRectMake(0, 0, 300, 120)];
 [self.view addSubview:countingLabel]; // 常规设置,QCountingLabel 继承 UILabel, 设置和 UILabel 一样
 countingLabel.center = self.view.center;
 countingLabel.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
 countingLabel.font = [UIFont systemFontOfSize:50];
 countingLabel.textColor = [UIColor redColor];
 countingLabel.textAlignment = NSTextAlignmentCenter;
 
- 也可以使用类方法一体式创建设置 - // 创建 QCountingLabel 对象
 QCountingLabel *countingLabel = [QCountingLabel q_countingLabelWithFrame:CGRectMake(50, 100, 300, 120)
 format:@"%f"
 positiveFormat:@"###,###.##"
 method:QCountingMethodEaseOut
 fromValue:20
 toValue:3048.64
 withDuration:10.0f
 completion:^{ NSLog(@"completion");
 }]; [self.view addSubview:countingLabel];
 
 
- 2、设置文本样式 - 不设置时默认为 @"%f" - // 设置文本样式
 countingLabel.format = @"%d";
 
- 也可以使用 block 设置普通样式或富文本样式 - // 设置文本样式,使用 block 可以根据不同的值设置多种不同的样式
 countingLabel.formatBlock = ^NSString *(CGFloat value) { NSInteger years = value / 12;
 NSInteger months = (NSInteger)value % 12; if (years == 0) { return [NSString stringWithFormat: @"%ld 个月", (long)months]; } else { return [NSString stringWithFormat: @"%ld 年, %ld 个月", (long)years, (long)months];
 }
 };
 
 
- 3、设置文本分隔符样式 - 设置金额等金融数字时可以奢姿带有千分位分隔符的浮点数样式 - // 设置分隔符样式
 countingLabel.positiveFormat = @"###,###.##";
 
 
- 4、设置文本变化方式 - 不设置时默认为 EaseInOut - // 设置文本变化方式
 countingLabel.method = QCountingMethodLinear;
 
 
- 5、设置变化范围及动画时间 - 不设置时间时默认为 2 秒 - [countingLabel q_countFromValue:10 toValue:100]; [countingLabel q_countFromValue:10 toValue:100 withDuration:1.0f];
 
 
- 6、设置变化完成时的回调 - 数字变化完成时,可以设置回调,再执行其他的操作 - // 设置变化完成时的回调
 countingLabel.completionBlock = ^void () { NSLog(@"completion");
 };
 
 
 
1.1 整数样式数字的变化
- 创建设置代码 - @property (nonatomic, strong) QCountingLabel *countingLabel; // 创建 QCountingLabel 对象
 self.countingLabel = [[QCountingLabel alloc] initWithFrame:CGRectMake(0, 0, 300, 120)];
 [self.view addSubview:self.countingLabel]; // 常规设置,QCountingLabel 继承 UILabel, 设置和 UILabel 一样
 self.countingLabel.center = self.view.center;
 self.countingLabel.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
 self.countingLabel.font = [UIFont systemFontOfSize:50];
 self.countingLabel.textColor = [UIColor redColor];
 self.countingLabel.textAlignment = NSTextAlignmentCenter; // 设置文本样式
 self.countingLabel.format = @"%d"; // 设置变化范围及动画时间
 [self.countingLabel q_countFromValue:10 toValue:1000 withDuration:1.0f];
 - 效果  
 
1.2 浮点数样式数字的变化
- 创建设置代码 - @property (nonatomic, strong) QCountingLabel *countingLabel; // 创建 QCountingLabel 对象
 self.countingLabel = [[QCountingLabel alloc] initWithFrame:CGRectMake(0, 0, 300, 120)];
 [self.view addSubview:self.countingLabel]; // 常规设置,QCountingLabel 继承 UILabel, 设置和 UILabel 一样
 self.countingLabel.center = self.view.center;
 self.countingLabel.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
 self.countingLabel.font = [UIFont systemFontOfSize:50];
 self.countingLabel.textColor = [UIColor redColor];
 self.countingLabel.textAlignment = NSTextAlignmentCenter; // 设置文本样式
 self.countingLabel.format = @"%.2f"; // 设置变化范围及动画时间
 [self.countingLabel q_countFromValue:0 toValue:3198.23 withDuration:1.0f];
 - 效果  
 
1.3 带有千分位分隔符的浮点数
- 创建设置代码 - @property (nonatomic, strong) QCountingLabel *countingLabel; // 创建 QCountingLabel 对象
 self.countingLabel = [[QCountingLabel alloc] initWithFrame:CGRectMake(0, 0, 300, 120)];
 [self.view addSubview:self.countingLabel]; // 常规设置,QCountingLabel 继承 UILabel, 设置和 UILabel 一样
 self.countingLabel.center = self.view.center;
 self.countingLabel.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
 self.countingLabel.font = [UIFont systemFontOfSize:50];
 self.countingLabel.textColor = [UIColor redColor];
 self.countingLabel.textAlignment = NSTextAlignmentCenter; // 设置文本样式
 self.countingLabel.format = @"%.2f"; // 设置分隔符样式
 self.countingLabel.positiveFormat = @"###,###.##"; // 设置变化范围及动画时间
 [self.countingLabel q_countFromValue:0 toValue:3048.64 withDuration:1.0f];
 - 效果  
 
iOS - Label 数字动态变化的更多相关文章
- Pop–实现任意iOS对象的任意属性的动态变化
		简介 Pop 是一个可扩展的动画引擎,可用于实现任意iOS对象的任意属性的动态变化,支持一般动画,弹性动画和渐变动画三种类型. 项目主页: pop 最新示例: 点击下载 注意: 官方代码中,并不包含实 ... 
- jQuery Validate input是动态变化的
		表单验证 $("#dataList").append("<div id='data"+dataNum+"' style='padding-top ... 
- iOS中关于动态Tableview中的cell数据传输的多线程问题解决之拙见
		iOS中关于动态Tableview中的cell数据传输的多线程问题解决之拙见 (2015-12-05 12:48:20)[编辑][删除] 转载▼ 首先我们先明确一下问题: 1.因为UI是在主线 ... 
- js实现页面时间动态变化
		利用函数嵌套和setTimeout函数实现时间动态变化 var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYe ... 
- 李洪强iOS开发之动态获取UILabel的bounds
		李洪强iOS开发之动态获取UILabel的bounds 在使用UILabel存放字符串时,经常需要获取label的长宽数据,本文列出了部分常用的计算方法. 1.获取宽度,获取字符串不折行单行显示时所需 ... 
- 编辑表格输入内容、根据input输入框输入数字动态生成表格行数、编辑表格内容提交传给后台数据处理
		编辑表格输入内容.根据input输入框输入数字动态生成表格行数.编辑表格内容提交传给后台数据处理 记录自己学习做的东西,写的小demo,希望对大家也有帮助! 代码如下: <!DOCTYPE ht ... 
- 初识IOS,Label控件的应用。
		初识IOS,Label控件的应用. // // ViewController.m // Gua.test // // Created by 郭美男 on 16/5/31. // Copyright © ... 
- ios 开发中 动态库 与静态库的区别
		使用静态库的好处 1,模块化,分工合作 2,避免少量改动经常导致大量的重复编译连接 3,也可以重用,注意不是共享使用 动态库使用有如下好处: 1使用动态库,可以将最终可执行文件体积缩小 2使用动态库, ... 
- 【转】提示框第三方库之MBProgressHUD iOS toast效果 动态提示框效果
		原文网址:http://www.zhimengzhe.com/IOSkaifa/37910.html MBProgressHUD是一个开源项目,实现了很多种样式的提示框,使用上简单.方便,并且可以对显 ... 
随机推荐
- Java网络编程技术1
			1. Java网络编程常用API 1.1 InetAddress类使用示例 1.1.1根据域名查找IP地址 获取用户通过命令行方式指定的域名,然后通过InetAddress对象来获取该域名对应的IP地 ... 
- ubuntu下用户的创建、修改
			一.1.添加用户 (1)创建一个新的用户username #sudo useradd username (2)设置用户username 的密码 #sudo passwd username 2.添加用户 ... 
- Android音乐播放-MediaPlayer
			当你坐公交无聊的时候,当你淹没在地铁中人潮中的时候,你是否想内心保持一份的安静呢,那么请带上耳机,打开你的音乐播放器,听一首老歌带你进入宁静的世界,音乐播放这个功能在智能手机出现之前,诺基亚时代,甚至 ... 
- C#汉字转拼音,可识别多音字,带声调,提供正向、逆向、双向分词算法的小程序
			用C#写了个汉字转拼音的小工具,和网上大部分工具不同,这个通过分词算法,解决了多音字的问题,并且提供声调,可开可关. 如题,用"银行 行不行 行家说了算"举例,如果转拼音却不能识别 ... 
- vue当前路由跳转初步研究
			一样闲话少说,直接上问题,如图: 也是消息面板,没想到一个小小的消息面板,碰到这么多坑,惆怅. 就是如果当前路由和跳转路由不一样时,正常跳转没有任何问题.但是如果一样时,就不会跳转了,用了很多方法,比 ... 
- 即时通讯之smack客户端配置
			之前学习了通过Openfire+spark+smack的模式来完成我们的即时通讯软件,上次我们已经完成了Openfire的安装和配置,这次我们继续完成我们的客户端部分. 1.首先我们通过百度smack ... 
- T-SQL with as 的用法(转)  SQL 下的递归查询  SQL2005(CTE) ,SQL2000(Function 递归)
			摘自: http://blog.csdn.net/bluefoxev/article/details/6779794 ------- SQL2005 方法 一.WITH AS的含义 WITH ... 
- [置顶] IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)
			首先了解一下CGContextRef: An opaque type that represents a Quartz 2D drawing environment. Graphics Context ... 
- ListView 拖拽
			private void ListView1_MouseMove(object sender, MouseEventArgs e) { Patientappointment appointment = ... 
- libFM 简介
			原文:https://eachcloudcn.blob.core.chinacloudapi.cn/clips/XOI1W.htm libFM全称为Factorization Machine Libr ... 
