iOS动画iOS Developer

iOS - 给数字的改变增加动效

2017-03-22  本文已影响122人  喵小泣

地址放在最前面:

简单实现动效改变数字-github

写在前面

最近在使用一些app时 , 发现他们点赞功能后面的数字增加或者减少会有一个动画改变的效果 , 很喜欢这样的小细节 , 于是自己动手做了一个类似demo ~~

效果图

结构

<small><small><small><small> 话说图好丑啊!!!!😝(看不到,看不到..)</small></small></small></small>

代码分析

//设置显示的数字
-(void)setNumberValue:(NSNumber *)numberValue {
    [self configScrollLayers:numberValue];
    _numberValue = numberValue;
}
CGFloat lastX = 0;
    //先根据对齐方式 , 计算最低位数字的x值
    if (_alignment == NSTextAlignmentRight) {
        lastX = self.frame.size.width - kAnimationNumberLabel_eachWidth - _contentEdgeInsets.right;
    } else if (_alignment == NSTextAlignmentLeft) {
        lastX = (kAnimationNumberLabel_eachWidth + _textMargin) * (numberValue.description.length - 1) + _contentEdgeInsets.left;
    } else if (_alignment == NSTextAlignmentCenter) {
        lastX = self.frame.size.width / 2.0 + (kAnimationNumberLabel_eachWidth * numberValue.description.length + _textMargin * (numberValue.description.length - 1)) / 2.0 - kAnimationNumberLabel_eachWidth;
    }
//如果之前数字的位数大于新数字的位数 , 将多余的layer移除存放如temLayers中 , 复用剩下的layer
    for (NSInteger i = numberValue.description.length; i<_scrollLayers.count; i++) {
        [_temLayers addObject:_scrollLayers[i]];
        [_scrollLayers[i] removeFromSuperlayer];
        [_scrollLayers removeObjectAtIndex:i];
        i--;
    }
    
    //如果之前的数字的位数小于新数字的位数 , 添加新的layer .
    for (NSInteger i = _scrollLayers.count; i<numberValue.description.length; i++) {
        CGRect frame = CGRectMake(lastX - i * kAnimationNumberLabel_eachWidth, 0, kAnimationNumberLabel_eachWidth, self.bounds.size.height);
        if (_temLayers.count) {
            _temLayers.lastObject.frame = frame;
            [_scrollLayers addObject:_temLayers.lastObject];
            [self.layer addSublayer:_temLayers.lastObject];
            [_temLayers removeObjectAtIndex:_temLayers.count - 1];
        } else {
            TextTransformationLayer *textLayer = [TextTransformationLayer layer];
            textLayer.frame = frame;
            
            [textLayer setTextArray:@[@".",@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9"] font:_font textColor:_textColor selectText:nil];
            [_scrollLayers addObject:textLayer];
            [self.layer addSublayer:textLayer];
        }
        
    }
//遍历layer 进行赋值和计算frame
    for (NSInteger i = 0; i<_scrollLayers.count; i++) {
        TextTransformationLayer *layer = _scrollLayers[i];
        layer.frame = CGRectMake(lastX - i * kAnimationNumberLabel_eachWidth - _textMargin * i, 0, kAnimationNumberLabel_eachWidth, self.bounds.size.height);
        
        //如果是0到9或者9到0 , 不进行动画展示
        BOOL animated;
        NSString *newStr = [numberValue.description substringWithRange:NSMakeRange(_scrollLayers.count - i - 1, 1)];

        if (i<_numberValue.description.length) {
            NSString *curStr = [_numberValue.description substringWithRange:NSMakeRange(_numberValue.description.length - i - 1, 1)];
            animated = (abs(newStr.intValue - curStr.intValue) < 9);
        } else {
            animated = NO;
        }
        
        animated = (animated && layer.selectText);
        [layer setSelectText:newStr animated:animated];;
    }

使用方法

使用的话就很简单了 , 先创建对象 , 然后进行赋值就好了

  NumberTransformationView *view = [[NumberTransformationView alloc] initWithFrame:frame font:[UIFont systemFontOfSize:18]];

  view.numberValue = @200;

总结

这个功能总体来说是比较简单的 , 我在动手coding之前大致思路是这样子的

  1. 首先要注意每个位数上的数字都应该有动画效果 , 所以不应该对整个数字做动画 , 而应该切分成若干个模块单独进行处理
  2. 切分后的模块应该注意复用 , 避免每次设值都要重新创建.
  3. 单独来看, 每个位数上的逻辑处理是一样的 , 所以应该单独拿出来作为一个功能.我这里对应的是TextTransformationLayer . 所有逻辑和动画效果都在由这个类完成 , NumberTransformationView只是对前者功能的一个组合.

写在最后

<big>**demo在最上 , 下载时欢迎顺手赏个star. (¬_¬)
以上.
**</big>

上一篇 下一篇

猜你喜欢

热点阅读