2013-12-23 64 views
6

我在iOS 7中測試新的條形碼掃描API時遇到了問題。此示例(單視圖應用程序)工作正常,但我想停止AVCaptureSession並在識別出EAN代碼後顯示第一個視圖由相機。iOS正確停止AVCaptureSession

[self.captureSession startRunning];不起作用。

如何正確停止AVCaptureSession?

#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. 
} 

回答

18

實際上,你可以因此停止AVCaptureSession:

[self.captureSession stopRunning]; 

但我懷疑你真正想要做的是,定格畫面。在屬性中保留對您的previewLayer的引用是有幫助的。然後:

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

你可以嘗試這樣的事情,定格畫面,然後幾秒鐘

- (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]; 

    }); 

    ... 

} 

更新
整個下架後解凍它:

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

喜代工,感謝您的回覆。我只是想將已識別的ean解析爲變量以備後用,並立即關閉捕獲會話。 – Boeringer

+0

@ Boeringer-見我的更新。希望能幫助到你... – foundry

0

你應該在主線程中調用performViewController。如下面:

-(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]; 
     }); 

    } 
} 

}