【问题标题】:Integrating ZBar reader in project: creating custom viewcontroller在项目中集成 ZBar 阅读器:创建自定义视图控制器
【发布时间】:2015-03-30 11:24:03
【问题描述】:

我已将此代码添加到我的项目中。它工作正常,从当前视图创建并显示 ZBarReaderViewController 的实例。

但是我希望能够定义我当前视图控制器的自定义区域并在该区域内显示 ZBarReaderViewController,同时仍显示我的“上一个/其他”视图。下面的代码显示了全屏模式下的视图控制器。

在界面生成器上,我只能在现有的 ViewController 中添加 UIView,因此我无法将自定义视图区域关联到 ZBarReaderViewController

我唯一能做的就是将它关联到一个 ZBarReaderView 实例,但是由于 ZBarReaderViewController 是一个封闭源(我只能看到我正在使用的 ZBar reader project 上的头文件)我我无法修改行为。

我该如何解决这个问题?

(IBAction)startScanning:(id)sender {

    NSLog(@"Scanning..");
    resultTextView.text = @"Scanning..";

    ZBarReaderViewController *codeReader = [ZBarReaderViewController new];
    codeReader.readerDelegate=self;
    codeReader.supportedOrientationsMask = ZBarOrientationMaskAll;

    ZBarImageScanner *scanner = codeReader.scanner;
    [scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];

    [self presentViewController:codeReader animated:YES completion:nil];
}

【问题讨论】:

  • 为什么不使用 iOS 框架呢?希望我为它提供一个示例类(使用 AVCaptureSession、AVCaptureVideoPreviewLayer 和 AVCaptureMetadataOutputObjectsDelegate)。
  • 请。会非常有用!

标签: ios objective-c uiviewcontroller zbar


【解决方案1】:

这里是一个扫描仪视图控制器的例子。我使用故事板创建视图,但您也可以通过编程方式或使用常规 nib 来创建。

首先,创建您的视图(比如说在故事板中)并在其中放置一个 UIView,您希望在其中显示扫描仪。

现在,让我们看一下视图控制器(请看里面的 cmets):

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

@interface ScannerViewController () <AVCaptureMetadataOutputObjectsDelegate>

// UI
@property (weak, nonatomic) IBOutlet UIView *viewPreview; // Connect it to the view you created in the storyboard, for the scanner preview

// Video
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *videoPreviewLayer;
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;
@property (nonatomic, strong) AVCaptureSession *flashLightSession;
@property (nonatomic) BOOL isReading;

@end

@implementation ScannerViewController

- (void)viewDidLoad
{
     [super viewDidLoad];

     // Initially make the captureSession object nil.
     _captureSession = nil;

    // Set the initial value of the flag to NO.
    _isReading = NO;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self startStopReading:nil];
}

- (IBAction)startStopReading:(id)sender
{
    if (!_isReading) {
        [self startReading];
    }
    else {
        // In this case the app is currently reading a QR code and it should stop doing so.
        [self stopReading];

    }

    // Set to the flag the exact opposite value of the one that currently has.
    _isReading = !_isReading;
}

#pragma mark - Private

- (BOOL)startReading
{
    NSError *error;

    // Get an instance of the AVCaptureDevice class to initialize a device object and provide the video
    // as the media type parameter.
    AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    // Get an instance of the AVCaptureDeviceInput class using the previous device object.
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&error];

    if (!input) {
        // If any error occurs, simply log the description of it and don't continue any more.
        NSLog(@"%@", [error localizedDescription]);
        return NO;
    }

    // Initialize the captureSession object.
    _captureSession = [[AVCaptureSession alloc] init];
    // Set the input device on the capture session.
    [_captureSession addInput:input];

    // Initialize a AVCaptureMetadataOutput object and set it as the output device to the capture session.
    AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
    [_captureSession addOutput:captureMetadataOutput];

    // Create a new serial dispatch queue.
    dispatch_queue_t dispatchQueue;
    dispatchQueue = dispatch_queue_create("myQueue", NULL);
    [captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
    [captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; // Add all the types you need, currently it is just QR code

    // Initialize the video preview layer and add it as a sublayer to the viewPreview view's layer.
    _videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
    [_videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    [_videoPreviewLayer setFrame:_viewPreview.layer.bounds];
    [_viewPreview.layer addSublayer:_videoPreviewLayer];

    // Start video capture.
    [_captureSession startRunning];

    return YES;
}

- (void)stopReading
{
    // Stop video capture and make the capture session object nil.
    [_captureSession stopRunning];
    _captureSession = nil;

    // Remove the video preview layer from the viewPreview view's layer.
    [_videoPreviewLayer removeFromSuperlayer];
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
   // Check if the metadataObjects array is not nil and it contains at least one object.
   if (metadataObjects != nil && [metadataObjects count] > 0) {

        [self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];

        _isReading = NO;

        // If the audio player is not nil, then play the sound effect.
        if (_audioPlayer) {
            [_audioPlayer play];
        }

        // This was my result, but you can search the metadataObjects array for what you need exactly
        NSString *code = [(AVMetadataMachineReadableCodeObject *)[metadataObjects objectAtIndex:0] stringValue];

    }

}

【讨论】:

  • 非常感谢代码。我将它集成到我的项目中,但是我需要了解如何捕获会话以及如何阅读代码。你能添加这个吗?如果没有,您可能会建议一个好的教程/起点吗?
  • 不知道为什么投反对票,也许我们需要重新表述你的问题。
  • 将其集成到您的代码后,您是否在视图中看到视频会话?
  • 我没有投反对票...对不起..我要投赞成票并接受,因为这是一个非常有用的答案..谢谢..实际上是的..是我投反对票但确实它不小心......稍后会重新投票(需要等待 1 小时)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-04
  • 2013-08-25
  • 1970-01-01
  • 2014-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多