支付宝UI篇-扫码和AR

支付宝UI篇-扫码和AR支付宝UI篇-扫码和AR

这里的UI实现,主要考验遮罩蒙板的使用。


具体看代码实现:代码链接


#import "IRCameraMask.h"

@implementation IRCameraMask
{
    CALayer *_bgLayer;
    CALayer *_mainLayer;
    CALayer *_scanLayer;
    
    float _radius;
    
    CABasicAnimation *_moveAnimation;
    CALayer *_moveLayer;
}

- (instancetype)init
{
    return [self initWithFrame:[UIScreen mainScreen].bounds];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    return [self initWithFrame:frame type:2];
}

- (instancetype)initWithFrame:(CGRect)frame type:(int)type;
{
    self = [super initWithFrame:frame];
    if (self)
    {
        _type = type;
        
        float edge    = 37;
        float radius2 = (self.bounds.size.width - 2 *edge);
        _radius = radius2/2.0;
        
        _bgLayer = [CALayer layer];
        [self.layer addSublayer:_bgLayer];
        
        float width = radius2+2;
        _scanLayer = [CALayer layer];
        _scanLayer.frame = CGRectMake(0, 0, width , width);
        [self.layer addSublayer:_scanLayer];
        
        CALayer *maskLayer = [CALayer layer];
        maskLayer.frame    = _scanLayer.bounds;
        _scanLayer.mask    = maskLayer;
        
        CALayer *moveLayer = [CALayer layer];
        moveLayer.frame    = _scanLayer.bounds;
        [_scanLayer addSublayer:moveLayer];
        
        CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
        moveAnimation.duration    = 1.75;
        moveAnimation.repeatCount = HUGE_VALF;
        [moveLayer addAnimation:moveAnimation forKey:@"AnimationMoveY"];
        
        _moveAnimation = moveAnimation;
        _moveLayer     = moveLayer;
        
        _mainLayer = [CALayer layer];
        [self.layer addSublayer:_mainLayer];
        
        _bgLayer.frame    = self.bounds;
        _mainLayer.frame  = self.bounds;
        
        [self changeType:_type];
    }
    return self;
}

- (void)changeType:(int)type
{
    _type = type;
    
    float offY      = 25;
    float fromValue = -_radius;
    float toValue   = _radius + offY;
    NSString *maskName = @"camera-loupe-mask";
    NSString *moveNmae = @"5";
    UIImage *mainImage = [UIImage imageNamed:@"camera-mask"];
    
    CGPoint scanCenter = CGPointMake(self.center.x,self.center.y - offY);
    
    CGRect rect = CGRectMake(scanCenter.x - _radius, scanCenter.y - _radius, _radius*2, _radius*2);
    
    _scanRect      = rect;
    _scanScaleRect = [self getScanCrop:rect readerViewBounds:self.bounds];
    
    if (_type == 1)
    {
        fromValue   = scanCenter.y - 3*_radius;
        toValue     = scanCenter.y - _radius;
        maskName    = @"scan-loupe-mask";
        moveNmae    = @"scan_net";
        mainImage   = [self getRectImageWithRect:rect];
        
        _mainLayer.mask = nil;
    } else
    {
        UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.bounds];
        UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:scanCenter
                                                                  radius:_radius
                                                              startAngle:0
                                                                endAngle:2 *M_PI
                                                               clockwise:NO];
        [path appendPath:circlePath];
        
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.path = path.CGPath;
        _mainLayer.mask = shapeLayer;
    }
    _moveLayer.contents      = (id)[UIImage imageNamed:moveNmae].CGImage;
    _scanLayer.mask.contents = (id)[UIImage imageNamed:maskName].CGImage;
    _scanLayer.center        = scanCenter;
    _moveAnimation.fromValue = [NSNumber numberWithFloat:fromValue];
    _moveAnimation.toValue   = [NSNumber numberWithFloat:toValue];
    _mainLayer.contents      = (id)mainImage.CGImage;
    
    [self stopAnimating];
    [self startAnimating];
}

- (void)startAnimating
{
    [_moveLayer addAnimation:_moveAnimation forKey:@"AnimationMoveY"];
}

- (void)stopAnimating
{
    [_moveLayer removeAnimationForKey:@"AnimationMoveY"];
}

- (void)setImage:(UIImage *)image
{
    _image = image;
    _bgLayer.contents = (id)image.CGImage;
}

- (UIImage *)getRectImageWithRect:(CGRect)rect
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 1.0);
    CGContextRef con = UIGraphicsGetCurrentContext();
    
    CGContextSetFillColorWithColor(con, [UIColor colorWithWhite:0 alpha:0.45].CGColor);
    CGContextFillRect(con, self.bounds);
    
    CGRect rects[] =
    {
        rect,
    };
    CGContextAddRects(con, rects, sizeof(rects)/sizeof(CGRect));
    
    CGContextSetBlendMode(con, kCGBlendModeClear);
    CGContextFillPath(con);
    
    UIImage *ima = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return ima;
}


#pragma mark-> 获取扫描区域的比例关系

- (CGRect)getScanCrop:(CGRect)rect readerViewBounds:(CGRect)readerViewBounds
{
    CGFloat x,y,width,height;
    
    x = (CGRectGetHeight(readerViewBounds)-CGRectGetHeight(rect))/2/CGRectGetHeight(readerViewBounds);
    y = (CGRectGetWidth(readerViewBounds)-CGRectGetWidth(rect))/2/CGRectGetWidth(readerViewBounds);
    width  = CGRectGetHeight(rect)/CGRectGetHeight(readerViewBounds);
    height = CGRectGetWidth(rect)/CGRectGetWidth(readerViewBounds);
    
    return CGRectMake(x, y, width, height);
}

@end



上一篇:关于索引扫描的极速调优实战(第二篇)


下一篇:TensorFlow在iOS和Mac上的使用