这里的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