这里的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
AI 代码解读