我有一个带有qr代码阅读器的应用程序。我在ViewWillAppear中设置了扫描仪:
// Create a new AVCaptureSession.
_session = [AVCaptureSession new];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
// Connect the input.
if(input)
{
[_session addInput:input];
}
else
{
NSLog(@"error: %@", error);
return;
}
// Connect the output.
AVCaptureMetadataOutput *output = [AVCaptureMetadataOutput new];
[_session addOutput:output];
NSLog(@"%@", [output availableMetadataObjectTypes]);
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// Connect the preview layer.
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.bounds = self.view.bounds;
_previewLayer.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
[self.view.layer addSublayer:_previewLayer];
// Start the AVSession.
[_session startRunning];
我实现了委托方法,如下所示:
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputMetadataObjects:(NSArray *)metadataObjects
fromConnection:(AVCaptureConnection *)connection {
// Iterate through all the visible metadata objects.
for (AVMetadataObject *metadata in metadataObjects) {
// Only care about QR codes.
if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) {
// Parse the QR code.
AVMetadataMachineReadableCodeObject *transformed =
(AVMetadataMachineReadableCodeObject *)[_previewLayer transformedMetadataObjectForMetadataObject:metadata];
// Stop the session.
[_previewLayer removeFromSuperlayer];
[_session stopRunning];
// Do other stuff, then push next view controller.
不幸的是,当我尝试运行它时,它会在呼叫停止后多次继续扫描qr代码。在我离开之后,我看到一堆错误说,"在意外状态下完成导航过渡。导航栏子视图树可能已损坏。"然后它崩溃了。我在这里找不到什么东西?
答案 0 :(得分:0)
我也有类似的问题。作为最硬件直接相关的功能,所有抓取的数据都会进入缓冲区。因此,您在停止会话后遇到的是从摄像机抓取并放入队列的最后一帧。解决方案(快速和脏)是创建一个BOOL变量(静态或iVar),它在停止运行之前改变其状态,并在委托方法的开头检查其状态。我现在手里还没有这份文件,但我很确定你可以直接向会议询问其running
属性和interrupted
的状态属性