123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- //
- // JTNumberScrollAnimatedView.m
- // JTNumberScrollAnimatedView
- //
- // Created by Jonathan Tribouharet
- //
- #import "JTNumberScrollAnimatedView.h"
- @interface JTNumberScrollAnimatedView(){
- NSMutableArray *numbersText;
- NSMutableArray *scrollLayers;
- NSMutableArray *scrollLabels;
- }
- @end
- @implementation JTNumberScrollAnimatedView
- - (instancetype)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if(!self){
- return nil;
- }
-
- [self commonInit];
-
- return self;
- }
- - (id)initWithCoder:(NSCoder *)aDecoder
- {
- self = [super initWithCoder:aDecoder];
- if(!self){
- return nil;
- }
-
- [self commonInit];
-
- return self;
- }
- - (void)commonInit
- {
- self.duration = 3;
- self.durationOffset = 0.5;
- self.density = 5;
- self.isAscending = YES;
- [self setValue:[NSNumber numberWithInt:50]];
-
- self.font = [UIFont fontWithName:kPFSCFont size:[UIFont systemFontSize]];
- self.textColor = [UIColor blackColor];
-
- numbersText = [NSMutableArray new];
- scrollLayers = [NSMutableArray new];
- scrollLabels = [NSMutableArray new];
- }
- - (void)setValue:(NSNumber *)value
- {
- self->_value = value;
- NSString *textValue = [self.value stringValue];
- self.minLength = textValue.length+1;
- [self prepareAnimations];
- }
- - (void)startAnimation
- {
- [self prepareAnimations];
- [self createAnimations];
- }
- - (void)stopAnimation
- {
- for(CALayer *layer in scrollLayers){
- [layer removeAnimationForKey:@"JTNumberScrollAnimatedView"];
- }
- }
- - (void)prepareAnimations
- {
- for(CALayer *layer in scrollLayers){
- [layer removeFromSuperlayer];
- }
-
- [numbersText removeAllObjects];
- [scrollLayers removeAllObjects];
- [scrollLabels removeAllObjects];
-
- [self createNumbersText];
- [self createScrollLayers];
- }
- - (void)createNumbersText
- {
- NSString *textValue = [self.value stringValue];
-
- for(NSInteger i = 0; i < (NSInteger)self.minLength - (NSInteger)[textValue length]; ++i){
- [numbersText addObject:@""];
- }
-
- for(NSUInteger i = 0; i < [textValue length]; ++i){
- [numbersText addObject:[textValue substringWithRange:NSMakeRange(i, 1)]];
- }
- }
- - (void)createScrollLayers
- {
- CGFloat width = 25;
- CGFloat height = 35;
-
- for(NSUInteger i = 0; i < numbersText.count; ++i){
- CAScrollLayer *layer = [CAScrollLayer layer];
- if (i==0) {
- layer.frame = CGRectMake(roundf(-100 * width), 0, width, height);
- }else{
- layer.frame = CGRectMake(roundf(i * width), 0, width, height);
- }
- [scrollLayers addObject:layer];
- [self.layer addSublayer:layer];
- }
-
- for(NSUInteger i = 0; i < numbersText.count; ++i){
- CAScrollLayer *layer = scrollLayers[i];
- NSString *numberText = numbersText[i];
- [self createContentForLayer:layer withNumberText:numberText];
- }
- }
- - (void)createContentForLayer:(CAScrollLayer *)scrollLayer withNumberText:(NSString *)numberText
- {
- NSInteger number = [numberText integerValue];
- NSMutableArray *textForScroll = [NSMutableArray new];
-
- for(NSUInteger i = 0; i < self.density + 1; ++i){
- [textForScroll addObject:[NSString stringWithFormat:@"%ld", (number + i) % 10]];
- }
-
- [textForScroll addObject:numberText];
-
- if(!self.isAscending){
- textForScroll = [[[textForScroll reverseObjectEnumerator] allObjects] mutableCopy];
- }
-
- CGFloat height = 0;
- for(NSString *text in textForScroll){
- UIImageView * textLabel = [self createLabel:text];
- textLabel.frame = CGRectMake(0, height, CGRectGetWidth(scrollLayer.frame), CGRectGetHeight(scrollLayer.frame));
- [scrollLayer addSublayer:textLabel.layer];
- [scrollLabels addObject:textLabel];
- height = CGRectGetMaxY(textLabel.frame);
- }
- }
- - (UIImageView *)createLabel:(NSString *)text
- {
- UIImageView *view = [[UIImageView alloc] init];
- view.contentMode = UIViewContentModeScaleAspectFit;
- view.image = [UIImage imageNamed:[NSString stringWithFormat:@"num_anim_%@",text]];
- return view;
- }
- - (void)createAnimations
- {
- CFTimeInterval duration = self.duration - ([numbersText count] * self.durationOffset);
- CFTimeInterval offset = 0;
- [scrollLayers removeObjectAtIndex:0];
- for(int i = (int)scrollLayers.count-1; i>=0; i--){
- CALayer *scrollLayer = scrollLayers[i];
- CGFloat maxY = [[scrollLayer.sublayers lastObject] frame].origin.y;
-
- CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"sublayerTransform.translation.y"];
- animation.duration = duration + offset;
- animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
-
- if(self.isAscending){
- animation.fromValue = [NSNumber numberWithFloat:-maxY];
- animation.toValue = @0;
- }
- else{
- animation.fromValue = @0;
- animation.toValue = [NSNumber numberWithFloat:-maxY];
- }
-
- [scrollLayer addAnimation:animation forKey:@"JTNumberScrollAnimatedView"];
-
- offset += self.durationOffset;
- }
-
- if (self.minLength < 5) {
- offset = offset + 2;
- }
-
- [self.delegate numberScrollAnimatedViewTime:offset];
-
- }
- @end
|