iOS自帶二維碼掃描

  • 今天項目需要做一個二維碼掃描,雖然有很多二維碼掃描的第三方可以用,但是考慮到項目中的需要,所以我放棄了使用三方庫,而采用了蘋果原生的掃描。
  • 原生的二維碼掃描有一個坑,那就是掃描范圍的確定。只要記得掃描范圍是X與Y互換位置,W與H互換位置,就沒有什么問題了。
  • 下面進入正題:
    1.因為使用原生二維碼掃描,所以需要加入頭文件添加delegate
#import <AVFoundation/AVFoundation.h>
<AVCaptureMetadataOutputObjectsDelegate>

2.接著是使用到的類

@property (strong,nonatomic)AVCaptureDevice * device;
@property (strong,nonatomic)AVCaptureDeviceInput * input;
@property (strong,nonatomic)AVCaptureMetadataOutput * output;
@property (strong,nonatomic)AVCaptureSession * session;
@property (weak, nonatomic) IBOutlet UIView *outputView;//xib中掃描的View
@property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;
@property (strong, nonatomic) NSTimer * timer;//為了做掃描動畫的定時器
@property (strong, nonatomic) UIImageView * lineImage;//掃描動畫的橫線

3.懶加載一個掃描動畫的圖片

-(UIImageView *)lineImage{
    if (!_lineImage) {
        CGFloat outputW = self.outputView.frame.size.width;
        _lineImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0,outputW, 2)];
        _lineImage.image = [UIImage imageNamed:@"ray"];
    }
    return _lineImage;
}

4.使用前的設置,我將它設置在了viewDidLoad當中

-viewDidLoad{
[super viewDidLoad];
   // Device
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

   // Input
    _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
    
    // Output
    _output = [[AVCaptureMetadataOutput alloc]init];
    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    // Session
    _session = [[AVCaptureSession alloc]init];
    [_session setSessionPreset:AVCaptureSessionPresetHigh];
    //連接輸入和輸出
    if ([_session canAddInput:self.input])
    {
        [_session addInput:self.input];
    }
    
    if ([_session canAddOutput:self.output])
    {
        [_session addOutput:self.output];
    }
//設置條碼類型
    _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
    
    //設置條碼位置
    CGFloat X = (ScreenW/2-100)/ScreenW;
    CGFloat Y = (ScreenH/2-100)/ScreenH;
    CGFloat W = 200/ScreenW;
    CGFloat H = 200/ScreenH;
    //設置掃描范圍(注意,X與Y交互,W與H交換)
    [_output setRectOfInterest:CGRectMake(Y, X, H, W)];
//添加掃描畫面
    _preview =[AVCaptureVideoPreviewLayer layerWithSession:_session];
    _preview.videoGravity =AVLayerVideoGravityResizeAspectFill;
    _preview.frame = CGRectMake(0, 0, ScreenW, ScreenH);//self.view.layer.bounds;
    [self.view.layer insertSublayer:_preview atIndex:0];
    //開始掃描
    [_session startRunning];

 //添加掃描動畫定時器
[self.outputView addSubview:self.lineImage];
    // Do any additional setup after loading the view from its nib.
    _timer = [NSTimer scheduledTimerWithTimeInterval:2.5f
                                              target:self
                                            selector:@selector(lineAction)
                                            userInfo:nil
                                             repeats:YES];
}

5.二維碼掃描的代理事件

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    NSString *stringValue;
    if ([metadataObjects count] >0){
        //停止掃描
        [_session stopRunning];
       AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
       stringValue = metadataObject.stringValue;//stringValue是掃描拿到的內(nèi)容,更具內(nèi)容進行后續(xù)工作。
    }
}

6.添加掃描動畫的事件

 - (void)lineAction{
    CGFloat outputW = self.outputView.frame.size.width;
    CGFloat outputH = self.outputView.frame.size.height;
    [UIView animateWithDuration:2.4f animations:^{
        CGRect frame = CGRectMake(0, outputH, outputW, 2);
        self.lineImage.frame = frame;
    } completion:^(BOOL finished) {
        CGRect frame = CGRectMake(0, 0, outputW, 2);
        self.lineImage.frame = frame;
    }];
}

7.該變掃描視屏方向

_preview.connection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation];
-(AVCaptureVideoOrientation) videoOrientationFromCurrentDeviceOrientation {
    switch (self.interfaceOrientation) {
        case UIInterfaceOrientationPortrait: {
            return AVCaptureVideoOrientationPortrait;
        }
        case UIInterfaceOrientationLandscapeLeft: {
            return AVCaptureVideoOrientationLandscapeLeft;
        }
        case UIInterfaceOrientationLandscapeRight: {
            return AVCaptureVideoOrientationLandscapeRight;
        }
        case UIInterfaceOrientationPortraitUpsideDown: {
            return AVCaptureVideoOrientationPortraitUpsideDown;
        }
        default:return AVCaptureVideoOrientationPortrait;
    }
}
  • 搞定......
  • 最后放上一張效果圖
原生的掃描就是快,??
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 分享的內(nèi)容,大家看了后,不管有什么問題或者建議,都可以說出來,我都會一一做答,一起加油啦 我的下一篇 < >需要的...
    邵瓊閱讀 864評論 0 0
  • #import "BaseViewController.h" @interface ScanCodeVC : Ba...
    這樣的我321閱讀 682評論 0 2
  • VLC的集成和使用 VLC介紹 VLC Media Player (VideoLAN) 為 Windows、Lin...
    Pocket閱讀 20,385評論 75 66
  • 自用-二維碼掃描模塊代碼 效果圖 直接上代碼 注釋寫的還算詳細-需要準備下面的東西,其中preView是要顯示的樣...
  • 晚上帶女兒在創(chuàng)業(yè)廣場玩,遇到晨,她逗著我女兒玩了一會兒,對我說:葉樓也結(jié)婚了,孩子比你的大不了二歲。 葉樓?已經(jīng)十...
    張玉曼閱讀 580評論 0 1

友情鏈接更多精彩內(nèi)容