2013-12-23 7 views
6

Ich habe ein Problem beim Testen der neuen Barcode-Scanning-API in iOS 7. Dieses Beispiel (Einzelansicht Anwendung) funktioniert gut, aber ich möchte die AVCaptureSession stoppen und zeigen die erste Ansicht nach einem EAN-Code erkannt wird durch die Kamera.iOS Korrekt stoppen AVCaptureSession

[self.captureSession startRunning]; funktioniert nicht.

Wie kann ich die AVCaptureSession korrekt stoppen?

#import "ViewController.h" 
#import <AVFoundation/AVFoundation.h> 

@interface ViewController() <AVCaptureMetadataOutputObjectsDelegate> 

@property (strong) AVCaptureSession *captureSession; 

@end 

@implementation ViewController 


- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.captureSession = [[AVCaptureSession alloc] init]; 
    AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    NSError *error = nil; 
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error]; 
    if(videoInput) 
     [self.captureSession addInput:videoInput]; 
    else 
     NSLog(@"Error: %@", error); 

    AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init]; 
    [self.captureSession addOutput:metadataOutput]; 
    [metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; 
    [metadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code]]; 

    AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; 
    previewLayer.frame = self.view.layer.bounds; 
    [self.view.layer addSublayer:previewLayer]; 

    [self.captureSession startRunning]; 

} 

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection 
{ 
    for(AVMetadataObject *metadataObject in metadataObjects) 
    { 
     AVMetadataMachineReadableCodeObject *readableObject = (AVMetadataMachineReadableCodeObject *)metadataObject; 
     if([metadataObject.type isEqualToString:AVMetadataObjectTypeQRCode]) 
     { 
      NSLog(@"QR Code = %@", readableObject.stringValue); 
     } 
     else if ([metadataObject.type isEqualToString:AVMetadataObjectTypeEAN13Code]) 
     { 
      NSLog(@"EAN 13 = %@", readableObject.stringValue); 



     } 
    } 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

Antwort

18

Sie können tatsächlich die AVCaptureSession stoppen also:

[self.captureSession stopRunning]; 

Aber ich vermute, was Sie wirklich wollen, ist es, den Bildschirm einzufrieren. Es ist hilfreich, einen Verweis auf Ihre previewLayer in einer Eigenschaft zu behalten. Dann:

[[self.previewLayer connection] setEnabled:NO]; 

Sie können so etwas wie dies versuchen, den Bildschirm einzufrieren und dann auftauen es nach ein paar Sekunden

- (void)  captureOutput:(AVCaptureOutput *)captureOutput 
    didOutputMetadataObjects:(NSArray *)metadataObjects 
      fromConnection:(AVCaptureConnection *)connection 
{ 
    [[self.previewLayer connection] setEnabled:NO]; 

    double delayInSeconds = 2.0; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 
            (int64_t)(delayInSeconds * NSEC_PER_SEC)); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
     [[self.previewLayer connection] setEnabled:YES]; 

    }); 

    ... 

} 

Update
voll Entlade:

[self.captureSession stopRunning]; 
[self.previewLayer removeFromSuperlayer]; 
self.previewLayer = nil; 
self.captureSession = nil; 
+0

hallo Gießerei, vielen Dank für Ihre Antwort. ich will nur den erkannten ean in einer variablen für die spätere verwendung analysieren und sofort die capture-session ohne verzögerung schließen. – Boeringer

+0

@ Boeringer - siehe mein Update. Ich hoffe es hilft... – foundry

0

Sie sollten den performViewController im Haupt-Thread aufrufen. unten wie:

-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{ 
if (metadataObjects != nil && [metadataObjects count] > 0) { 
    AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0]; 
    if ([[metadataObj type] isEqualToString:AVMetadataObjectTypeQRCode]) { 

     [self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO]; 
     // should call the view controller transfer method in the main thread 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self performSegueWithIdentifier:@"show first view controller" sender: self]; 
     }); 

    } 
} 

}

Verwandte Themen