iOS原生自定义二维码扫描界面(类似微信)

本次内容的效果图



.h文件

#import "RootViewController.h"


@interface SQCodeViewController : RootViewController//继承根视图,主要继承根视图的导航控制


@end



.m文件

#import "SQCodeViewController.h"

#import <AVFoundation/AVFoundation.h>//原生二维码扫描必须导入这个框架

#define QRCodeWidth  260.0   //正方形二维码的边长

#define SCREENWidth  [UIScreenmainScreen].bounds.size.width   //设备屏幕的宽度

#define SCREENHeight [UIScreen mainScreen].bounds.size.height //设备屏幕的高度



@interface SQCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic,strong)AVCaptureSession *session;

@end


@implementation SQCodeViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    [self onSetTitleView:@"二维码扫描结果"type:TitleLogo];//调用根视图的方法,自定义导航控制器的样式。这个根据读者的实际情况而定。

    self.navigationController.toolbarHidden = YES;//如果你的根视图有底部工具栏,这行代码可以隐藏底部的工具栏


    [self setupMaskView];//设置扫描区域之外的阴影视图

    

    [self setupScanWindowView];//设置扫描二维码区域的视图

    

    [self beginScanning];//开始扫二维码

}


- (void)setupMaskView

{

    //设置统一的视图颜色和视图的透明度

    UIColor *color = [UIColor blackColor];

    float alpha = 0.7;


    //设置扫描区域外部上部的视图

    UIView *topView = [[UIView alloc]init];

    topView.frame = CGRectMake(0, 64, SCREENWidth, (SCREENHeight-64-QRCodeWidth)/2.0-64);

    topView.backgroundColor = color;

    topView.alpha = alpha;


    //设置扫描区域外部左边的视图

    UIView *leftView = [[UIView alloc]init];

    leftView.frame = CGRectMake(0, 64+topView.frame.size.height, (SCREENWidth-QRCodeWidth)/2.0,QRCodeWidth);

    leftView.backgroundColor = color;

    leftView.alpha = alpha;


    //设置扫描区域外部右边的视图

    UIView *rightView = [[UIViewalloc]init];

    rightView.frame = CGRectMake((SCREENWidth-QRCodeWidth)/2.0+QRCodeWidth,64+topView.frame.size.height, (SCREENWidth-QRCodeWidth)/2.0,QRCodeWidth);

    rightView.backgroundColor = color;

    rightView.alpha = alpha;


    //设置扫描区域外部底部的视图

    UIView *botView = [[UIViewalloc]init];

    botView.frame = CGRectMake(0, 64+QRCodeWidth+topView.frame.size.height,SCREENWidth,SCREENHeight-64-QRCodeWidth-topView.frame.size.height);

    botView.backgroundColor = color;

    botView.alpha = alpha;


    //将设置好的扫描二维码区域之外的视图添加到视图图层上

    [self.viewaddSubview:topView];

    [self.viewaddSubview:leftView];

    [self.viewaddSubview:rightView];

    [self.viewaddSubview:botView];

}




- (void)setupScanWindowView

{

    //设置扫描区域的位置(考虑导航栏和电池条的高度为64)

    UIView *scanWindow = [[UIViewalloc]initWithFrame:CGRectMake((SCREENWidth-QRCodeWidth)/2.0,(SCREENHeight-QRCodeWidth-64)/2.0,QRCodeWidth,QRCodeWidth)];

    scanWindow.clipsToBounds = YES;

    [self.viewaddSubview:scanWindow];

    

    //设置扫描区域的动画效果

    CGFloat scanNetImageViewH = 241;

    CGFloat scanNetImageViewW = scanWindow.frame.size.width;

    UIImageView *scanNetImageView = [[UIImageViewalloc]initWithImage:[UIImageimageNamed:@"scan_net"]];

    scanNetImageView.frame = CGRectMake(0, -scanNetImageViewH, scanNetImageViewW, scanNetImageViewH);

    CABasicAnimation *scanNetAnimation = [CABasicAnimationanimation];

    scanNetAnimation.keyPath =@"transform.translation.y";

    scanNetAnimation.byValue = @(QRCodeWidth);

    scanNetAnimation.duration = 1.0;

    scanNetAnimation.repeatCount = MAXFLOAT;

    [scanNetImageView.layer addAnimation:scanNetAnimation forKey:nil];

    [scanWindow addSubview:scanNetImageView];

    

    //设置扫描区域的四个角的边框

    CGFloat buttonWH = 18;

    UIButton *topLeft = [[UIButtonalloc]initWithFrame:CGRectMake(0,0, buttonWH, buttonWH)];

    [topLeft setImage:[UIImageimageNamed:@"scan_1"]forState:UIControlStateNormal];

    [scanWindow addSubview:topLeft];

    

    UIButton *topRight = [[UIButtonalloc]initWithFrame:CGRectMake(QRCodeWidth - buttonWH,0, buttonWH, buttonWH)];

    [topRight setImage:[UIImageimageNamed:@"scan_2"]forState:UIControlStateNormal];

    [scanWindow addSubview:topRight];

    

    UIButton *bottomLeft = [[UIButtonalloc]initWithFrame:CGRectMake(0,QRCodeWidth - buttonWH, buttonWH, buttonWH)];

    [bottomLeft setImage:[UIImageimageNamed:@"scan_3"]forState:UIControlStateNormal];

    [scanWindow addSubview:bottomLeft];

    

    UIButton *bottomRight = [[UIButtonalloc]initWithFrame:CGRectMake(QRCodeWidth-buttonWH,QRCodeWidth-buttonWH, buttonWH, buttonWH)];

    [bottomRight setImage:[UIImageimageNamed:@"scan_4"]forState:UIControlStateNormal];

    [scanWindow addSubview:bottomRight];

}


- (void)beginScanning

{

    //获取摄像设备

    AVCaptureDevice * device = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

    //创建输入流

    AVCaptureDeviceInput * input = [AVCaptureDeviceInputdeviceInputWithDevice:deviceerror:nil];

    if (!input) return;

    //创建输出流

    AVCaptureMetadataOutput * output = [[AVCaptureMetadataOutputalloc]init];

    

    //特别注意的地方:有效的扫描区域,定位是以设置的右顶点为原点。屏幕宽所在的那条线为y轴,屏幕高所在的线为x轴

    CGFloat x = ((SCREENHeight-QRCodeWidth-64)/2.0)/SCREENHeight;

    CGFloat y = ((SCREENWidth-QRCodeWidth)/2.0)/SCREENWidth;

    CGFloat width = QRCodeWidth/SCREENHeight;

    CGFloat height = QRCodeWidth/self.SCREENWidth;

    output.rectOfInterest = CGRectMake(x, y, width, height);


    //设置代理在主线程里刷新

    [output setMetadataObjectsDelegate:selfqueue:dispatch_get_main_queue()];

    

    //初始化链接对象

    _session = [[AVCaptureSessionalloc]init];

    //高质量采集率

    [_sessionsetSessionPreset:AVCaptureSessionPresetHigh];

    

    [_session addInput:input];

    [_session addOutput:output];

    //设置扫码支持的编码格式(如下设置条形码和二维码兼容)

    output.metadataObjectTypes=@[AVMetadataObjectTypeQRCode,AVMetadataObjectTypeEAN13Code,AVMetadataObjectTypeEAN8Code,AVMetadataObjectTypeCode128Code];

    

    AVCaptureVideoPreviewLayer * layer = [AVCaptureVideoPreviewLayerlayerWithSession:_session];

    layer.videoGravity=AVLayerVideoGravityResizeAspectFill;

    layer.frame=self.view.layer.bounds;

    [self.view.layerinsertSublayer:layeratIndex:0];

    //开始捕获

    [_sessionstartRunning];

    

}


-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{

    if (metadataObjects.count>0) {

        [_session stopRunning];

        //得到二维码上的所有数据

        AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjectsobjectAtIndex :0 ];

        NSString *str = metadataObject.stringValue;

        NSLog(@"%@",str);

    }

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值