效果图
实现原理
数学原理
当前展示的数值 = 开始数值 + (结束数值 - 开始数值)* 当前时间进度(百分比)
UI逻辑
继承于UILabel , 只添加 数量增加功能,不涉及UI,UI样式完全外部定义,复用性好
核心代码
.h
@interface LBCountNumberLabel : UILabel
/// 展示数量变化
/// @param start 开始数量
/// @param end 结束数量
/// @param timeInterval 时间
- (void)showFromStartNum:(NSInteger)start
endNum:(NSInteger)end
duration:(CGFloat)timeInterval;
@end
NS_ASSUME_NONNULL_END
.m
#import "LBCountNumberLabel.h"
@interface LBCountNumberLabel ()
///计时器
@property (nonatomic, strong) CADisplayLink *link;
///开始时间
@property (nonatomic, assign) NSTimeInterval startTime;
///进度
@property (nonatomic, assign) CGFloat progress;
/// 总时长
@property (nonatomic, assign) CGFloat duration;
///开始值
@property (nonatomic, assign) NSInteger startValue;
///结束值
@property (nonatomic, assign) NSInteger endValue;
///当前展示的值
@property (nonatomic, assign) NSInteger currentValue;
@end
@implementation LBCountNumberLabel
- (void)showFromStartNum:(NSInteger)statr
endNum:(NSInteger)end
duration:(CGFloat)timeInterval
{
self.startValue = statr;
self.endValue = end;
self.duration = timeInterval;
self.currentValue = statr;
[self.link addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
- (void)linkSelector
{
if (self.currentValue >= self.endValue) {
self.currentValue = self.endValue;
self.text = [NSString stringWithFormat:@"%ld",self.currentValue];
[self.link invalidate];
self.link = nil;
return;
}
NSTimeInterval now = [NSDate timeIntervalSinceReferenceDate];
if (self.startTime == 0) {
self.startTime = now;
}
self.currentValue = self.startValue + (self.endValue - self.startValue) * (now - self.startTime) / self.duration;
self.text = [NSString stringWithFormat:@"%ld",self.currentValue];
}
#pragma mark - lazy load
- (CADisplayLink *)link
{
if (!_link) {
_link = [CADisplayLink displayLinkWithTarget:self selector:@selector(linkSelector)];
/// 每秒钟的帧数
_link.preferredFramesPerSecond = 10;
}
return _link;
}
@end