金额跳动动画效果
引言:
# 一. 效果
# 二. 代码实现
#import <UIKit/UIKit.h>
@interface UILabel (Extension)
/// 跳动文字
@property (nonatomic, strong) NSNumber *lc_number;
@end
UILabel+Extension.m: 通过 runtime 建立属性(setter/getter方法)
#import "UILabel+Extension.h"
#import <objc/runtime.h>
#define kTimer @"timer"
#define kAnimatedNumber @"animatedNumber"
#define kValueString @"valueString"
#define kRangeNumberKey @"RangeKey" // 每次数字跳动相差的间隔数
#define kBeginNumberKey @"BeginNumberKey" // 起始数字
#define kEndNumberKey @"EndNumberKey" // 结束跳动时的数字
#define kFrequency 1.0/30.0f // 数字跳动频率
#define kRangeNumber(endNumber,duration) (endNumber * kFrequency)/duration
@interface UILabel ()
@property (nonatomic, strong) NSNumber *animatedNumber;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) NSString *valueString;
@end
@implementation UILabel (Extension)
#pragma mark - ------ UI ------
- (void)setLc_number:(NSNumber *)lc_number {
[self dw_setNumber:lc_number duration:1.0];
}
- (void)setAnimatedNumber:(NSNumber *)animatedNumber {
objc_setAssociatedObject(self, kAnimatedNumber, animatedNumber, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)animatedNumber {
return objc_getAssociatedObject(self, kAnimatedNumber);
}
- (void)setTimer:(NSTimer *)timer {
objc_setAssociatedObject(self, kTimer, timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSTimer *)timer {
return objc_getAssociatedObject(self, kTimer);
}
-(void)setValueString:(NSString *)valueString {
objc_setAssociatedObject(self, kValueString, valueString, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)valueString {
return objc_getAssociatedObject(self, kValueString);
}
- (void)dw_setNumber:(NSNumber *)number duration:(NSTimeInterval)duration {
[self.timer invalidate];
self.timer = nil;
//变量初始化
self.animatedNumber = @(0);
double beginNumber = 1;
double endNumber = [number doubleValue];
NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithCapacity:0];
[userInfo setObject:@(beginNumber) forKey:kBeginNumberKey];
[userInfo setObject:number forKey:kEndNumberKey];
[userInfo setObject:@(kRangeNumber(endNumber, duration)) forKey:kRangeNumberKey];
// 添加定时器,添加到NSRunLoop中
self.timer = [NSTimer scheduledTimerWithTimeInterval:kFrequency target:self selector:@selector(changeAnimation:) userInfo:userInfo repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
- (void)changeAnimation:(NSTimer *)timer{
NSMutableDictionary *info = timer.userInfo;
double begin = ((NSNumber *)[info objectForKey:kBeginNumberKey]).doubleValue;
double end = ((NSNumber *)[info objectForKey:kEndNumberKey]).doubleValue;
double range = ((NSNumber *)[info objectForKey:kRangeNumberKey]).doubleValue;
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterNoStyle];
[formatter setFormatWidth:9];
[formatter setPositiveFormat:@",##0.00"];
double value = self.valueString.doubleValue;
if (value == 0) {
self.valueString = [NSString stringWithFormat:@"%f", begin];
self.text = [NSString stringWithFormat:@"%.@",[formatter stringFromNumber:@(begin)]];
} else if (value >= end) {
self.text = [NSString stringWithFormat:@"%.@",[formatter stringFromNumber:@(end)]];
self.valueString = [NSString stringWithFormat:@"%f", begin];
[self.timer invalidate];
self.timer = nil;
return;
} else {
value += range;
self.valueString = [NSString stringWithFormat:@"%f", value];
self.text = [NSString stringWithFormat:@"%.@",[formatter stringFromNumber:@(value)]];
}
}