美文网首页iOS开发
模仿苹果输入法中录音变化动画

模仿苹果输入法中录音变化动画

作者: iOS104 | 来源:发表于2017-03-04 17:54 被阅读89次

    最近工作中需要做一个类似于苹果输入法中语音识别的动画,方便用户通过语音,去控制智能设备。考虑了两种方案

    GitHub地址,欢迎大家star

    • 苹果自带输入法的声音动画
    Paste_Image.png
    • 下面是我自己实现的两种动画的UI
    11.gif

    方案1

    采用CAReplicatorLayer

    • 缺点:不能实时的根据声音的大小来调节动画的幅度,所以不能满足要求

    利用CAReplicatorLayer实现

    • 1、什么是CAReplicatorLayer?
    • 一种可以复制自己子层的layer,并且复制出来的layer和原生子层有同样的属性,位置,形变,动画。
    • 2、CAReplicatorLayer属性
    • instanceCount: 子层总数(包括原生子层)
    • instanceDelay: 复制子层动画延迟时长
    • instanceTransform: 复制子层形变(不包括原生子层),每个复制子层都是相对上一个。
    • instanceColor: 子层颜色,会和原生子层背景色冲突,因此二者选其一设置。
    • instanceRedOffset、instanceGreenOffset、instanceBlueOffset、instanceAlphaOffset: 颜色通道偏移量,每个复制子层都是相对上一个的偏移量。

    直接上代码

        CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer];
        replicatorLayer.frame = CGRectMake(50, 50, 200, 100);
        replicatorLayer.backgroundColor = [UIColor lightGrayColor].CGColor;
        // 设置4个子层,3个复制层
        replicatorLayer.instanceCount = 4;
        // 设置复制子层的相对位置,每个x轴相差40
        replicatorLayer.instanceTransform = CATransform3DMakeTranslation(30, 0, 0);
        // 设置复制子层的延迟动画时长
        replicatorLayer.instanceDelay = 0.1;
        [self.view.layer addSublayer:replicatorLayer];
        
        CALayer *layer = [CALayer layer];
        layer.backgroundColor = [UIColor redColor].CGColor;
        layer.bounds = CGRectMake(0, 0, 10, 80);
        layer.position = CGPointMake(30, 50);
        layer.cornerRadius = 7.5;
        layer.masksToBounds = YES;
        [replicatorLayer addSublayer:layer];
        
        CABasicAnimation *animation = [CABasicAnimation animation];
        animation.keyPath = @"transform.scale.y";
        animation.toValue = @(0.1);
        animation.autoreverses = YES;
        animation.repeatCount = MAXFLOAT;
        animation.duration = 0.3;
        [layer addAnimation:animation forKey:nil];
    

    方案2:

    采用 CADisplayLink UIBezierPath CAShapeLayer

    • 可以根据声音的大小实时的修改动画的幅度
    • 关于知识点详细介绍,可以看我另外的一篇文章
    • 我这边采用随机数来模拟声音大小变化

    直接上代码:

    #import "SpeedWaveShapeLayerView.h"
    
    #define HEXCOLORA(rgbValue, a) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16)) / 255.0 green:((float)((rgbValue & 0xFF00) >> 8)) / 255.0 blue:((float)(rgbValue & 0xFF)) / 255.0 alpha:a]
    #define HEXCOLOR(rgbValue) HEXCOLORA(rgbValue, 1.0)
    
    
    @interface SpeedWaveShapeLayerView()
    
    @property (nonatomic, strong) NSMutableArray *itemArray;
    @property (nonatomic, strong) NSMutableArray *levelArray;
    @property (nonatomic, assign) NSUInteger numberOfItems;
    
    @end
    
    @implementation SpeedWaveShapeLayerView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            
            _numberOfItems = 9;
            _levelArray = [NSMutableArray array];
            _itemArray = [NSMutableArray array];
        }
        
        return self;
    }
    
    - (void)setItemLevelCallback:(void (^)())itemLevelCallback {
        _itemLevelCallback = itemLevelCallback;
        
        CADisplayLink *displaylink = [CADisplayLink displayLinkWithTarget:_itemLevelCallback selector:@selector(invoke)];
        displaylink.frameInterval = 6;
        [displaylink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
        
        for (int i = 0; i < _numberOfItems; i++) {
            CAShapeLayer *itemline = [CAShapeLayer layer];
            itemline.lineCap       = kCALineCapRound;
            itemline.lineJoin      = kCALineJoinRound;
            itemline.fillColor     = [[UIColor clearColor] CGColor];
            [itemline setLineWidth:4];
            if (i == 0 || i == 1 || i == _numberOfItems - 1 || i == _numberOfItems - 2) {
                itemline.strokeColor   = HEXCOLORA(0xff2600, 0.1).CGColor;
            } else if (i == 2 || i == _numberOfItems - 3) {
                itemline.strokeColor   = HEXCOLORA(0xff2600, 0.4).CGColor;
            } else {
                itemline.strokeColor   = HEXCOLORA(0xff2600, 1.0).CGColor;
            }
            
            [self.layer addSublayer:itemline];
            [self.itemArray addObject:itemline];
            
            [self.levelArray addObject:@(2)];
        }
    }
    
    - (void)updateWare {
        UIGraphicsBeginImageContext(self.frame.size);
        float left = (self.frame.size.width - 10 * _numberOfItems) / 2.0;
        for (int i = 0; i < _numberOfItems; i++) {
            UIBezierPath *itemLinePath = [UIBezierPath bezierPath];
            float y = [[self.levelArray objectAtIndex:i] intValue];
            if (i == 0 || i == _numberOfItems - 1) {
                y = y * 3 / 7.0;
            } else if (i == 1 || i == _numberOfItems - 2) {
                y = y * 2 / 7.0;
            } else if (i == 2 || i == _numberOfItems - 3) {
                y = y * 3 / 7.0;
            } else if (i == 3 || i == _numberOfItems - 4) {
                y = y * 4 / 7.0;
            }
            
            [itemLinePath moveToPoint:CGPointMake(left + 10 * i, 30 + y)];
            [itemLinePath addLineToPoint:CGPointMake(left + 10 * i, 30 - y)];
            CAShapeLayer *shapeLayer = self.itemArray[i];
            shapeLayer.path = [itemLinePath CGPath];
        }
        UIGraphicsEndImageContext();
    }
    
    - (void)setLevel:(NSInteger)level {
        if (level < 3) {
            level = 3;
        }
        _level = level;
        
        [self.levelArray removeObjectAtIndex:self.numberOfItems - 1];
        [self.levelArray insertObject:@(level) atIndex:0];
        [self updateWare];
    }
    @end
    

    常用的Layer子类

    常用的Layer子类.png

    这里我主要用了 CAReplicationLayer 和 CAShapeLayer

    相关文章

      网友评论

        本文标题:模仿苹果输入法中录音变化动画

        本文链接:https://www.haomeiwen.com/subject/ngjjgttx.html