美文网首页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