4

我正在使用 zbarsdk 来读取条形码。它工作正常,但我的问题是我已将覆盖视图添加到 ZBarReaderViewController (我的代码中的阅读器)。所以现在我尝试添加点击聚焦功能。但它正在崩溃。下面是我的代码。提前致谢 。任何想法将不胜感激。

-(IBAction)scanBarCode:(id)sender
{
    barcodeClicked = 1;

    NSLog(@"TBD: scan barcode here...");
    // ADD: present a barcode reader that scans from the camera feed
    reader = [ZBarReaderViewController new];
    reader.readerDelegate = self;
    reader.supportedOrientationsMask = ZBarOrientationMaskAll;

    ZBarImageScanner *scanner = reader.scanner;
    // TODO: (optional) additional reader configuration here

    // EXAMPLE: disable rarely used I2/5 to improve performance
    [scanner setSymbology: ZBAR_I25
                   config: ZBAR_CFG_ENABLE
                       to: 0];
    reader.showsZBarControls = NO;

    UIView *ovlView = [[UIView alloc] init];
    [ovlView setFrame:CGRectMake(0, 0, 320, 480)];
    [ovlView setBackgroundColor:[UIColor clearColor]];

    UIImageView *leftBracket = [[UIImageView alloc] init];
    [leftBracket setFrame:CGRectMake(21, 100, 278, 15)];
    [leftBracket setImage:[UIImage imageNamed:@"TopBracket.png"]];

    UIImageView *rightBracket = [[UIImageView alloc] init];
    [rightBracket setFrame:CGRectMake(21, 240, 278, 15)];
    [rightBracket setImage:[UIImage imageNamed:@"BottomBracket.png"]];

    UIToolbar *bottomBar = [[UIToolbar alloc] init];
    [bottomBar setBarStyle:UIBarStyleBlackOpaque];

    if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height * [UIScreen mainScreen].scale >= 1136)
    {
        [bottomBar setFrame:CGRectMake(0, 524, 320, 44)];
    }
    else
        [bottomBar setFrame:CGRectMake(0, 436, 320, 44)];

    UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelCamera)];
    /*UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                                                              target:nil
                                                                              action:nil];*/
    //UIBarButtonItem *infoButton = [[UIBarButtonItem alloc] initWithTitle:@" Info " style:UIBarButtonItemStyleBordered target:self action:@selector(infoButton)];
    /*UIButton *info = [UIButton buttonWithType:UIButtonTypeInfoLight];
    [info addTarget:self action:@selector(infoButton) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *infoButton = [[UIBarButtonItem alloc] initWithCustomView:info];

    [bottomBar setItems:[NSArray arrayWithObjects:cancel,flexItem,infoButton, nil]];*/

    [bottomBar setItems:[NSArray arrayWithObjects:cancel, nil]];

    [ovlView addSubview:leftBracket];
    [ovlView addSubview:rightBracket];
    [ovlView addSubview:bottomBar];

    reader.cameraOverlayView = ovlView;

    // present and release the controller
    [self presentModalViewController:reader
                            animated: YES];
    [reader release];
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UIView * previewView = [[[[[[[[[[
                                     reader.view // UILayoutContainerView
                                     subviews] objectAtIndex:0] // UINavigationTransitionView
                                   subviews] objectAtIndex:0] // UIViewControllerWrapperView
                                 subviews] objectAtIndex:0] // UIView
                               subviews] objectAtIndex:0] // PLCameraView
                             subviews] objectAtIndex:0]; // PLPreviewView
    [previewView touchesBegan:touches withEvent:event];
}
4

2 回答 2

10

感谢 MacN00b 的回答!这为我指明了正确的方向。我已经为 zbarViewController 实现了点击焦点。这是想法:

您可以通过将自定义视图分配给其 cameraOverlayView 来将自定义视图添加到 zbarViewController。然后将 TapGestureRecagonizer 添加到自定义视图以捕捉点击。然后,获取接触点并使相机聚焦到接触点。您可能希望在触摸点周围添加一个小矩形(这就是我所做的)。

这是代码(将自定义视图分配给cameraOverlayView:

UIView *view = [[UIView alloc] init];
UITapGestureRecognizer* tapScanner = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(focusAtPoint:)];
[view addGestureRecognizer:tapScanner];    
reader.cameraOverlayView = view;

然后在选择器focusAtPoint

- (void)focusAtPoint:(id) sender{
    CGPoint touchPoint = [(UITapGestureRecognizer*)sender locationInView:_reader.cameraOverlayView];
    double focus_x = touchPoint.x/_reader.cameraOverlayView.frame.size.width;
    double focus_y = (touchPoint.y+66)/_reader.cameraOverlayView.frame.size.height;
    NSError *error;
    NSArray *devices = [AVCaptureDevice devices];
    for (AVCaptureDevice *device in devices){
        NSLog(@"Device name: %@", [device localizedName]);
        if ([device hasMediaType:AVMediaTypeVideo]) {
            if ([device position] == AVCaptureDevicePositionBack) {
                NSLog(@"Device position : back");
                CGPoint point = CGPointMake(focus_y, 1-focus_x);
                if ([device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus] && [device lockForConfiguration:&error]){
                    [device setFocusPointOfInterest:point];
                    CGRect rect = CGRectMake(touchPoint.x-30, touchPoint.y-30, 60, 60);
                    UIView *focusRect = [[UIView alloc] initWithFrame:rect];
                    focusRect.layer.borderColor = [UIColor whiteColor].CGColor;
                    focusRect.layer.borderWidth = 2;
                    focusRect.tag = 99;
                    [_reader.cameraOverlayView addSubview:focusRect];
                    [NSTimer scheduledTimerWithTimeInterval: 1
                                target: self
                                selector: @selector(dismissFocusRect)
                                userInfo: nil
                                repeats: NO];
                    [device setFocusMode:AVCaptureFocusModeAutoFocus];
                    [device unlockForConfiguration];
                }
            }
        }
    }
}

我在触摸点周围添加了一个白色矩形,然后使用选择器dismissFocusRect 来消除这个矩形。这是代码:

- (void) dismissFocusRect{
    for (UIView *subView in _reader.cameraOverlayView.subviews)
    {
        if (subView.tag == 99)
        {
            [subView removeFromSuperview];
        }
    }
}

我希望这会有所帮助!

于 2013-01-31T14:38:13.643 回答
1

在“Focus Modes”部分查看苹果的这个文档:https ://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html它谈到了如何实现tap正确对焦。我会尝试通过

CGRect screenRect = [[UIScreen mainScreen] bounds];
    screenWidth = screenRect.size.width;
    screenHeight = screenRect.size.height;  
    double focus_x = thisFocusPoint.center.x/screenWidth;
    double focus_y = thisFocusPoint.center.y/screenHeight;

    [[self captureManager].videoDevice lockForConfiguration:&error];
    [[self captureManager].videoDevice setFocusPointOfInterest:CGPointMake(focus_x,focus_y)];

好吧,如果您正在使用该视图控制器,那么添加一个应该可以在barcodeviewcontroller中实现的(void)怎么样。

- (void) focusAtPoint:(CGPoint)point

{

    AVCaptureDevice *device = [[self videoInput] device];

    if ([device isFocusPointOfInterestSupported] && [device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {

        NSError *error;

        if ([device lockForConfiguration:&error]) {

            [device setFocusPointOfInterest:point];

            [device setFocusMode:AVCaptureFocusModeAutoFocus];

            [device unlockForConfiguration];

        } else {

            id delegate = [self delegate];

            if ([delegate respondsToSelector:@selector(acquiringDeviceLockFailedWithError:)]) {

                [delegate acquiringDeviceLockFailedWithError:error];

            }

        }        

    }

}
于 2012-12-24T07:10:01.277 回答