I am using the zbarsdk to read the barcodes . It is working fine , but my problem is I have added the overlay view to the ZBarReaderViewController (reader in my code ). So now I tried to add the tap to focus functionality . But it is crashing . Below is my code . Thanks in advance . Any ideas would be grateful .
-(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];
}
Thanks for MacN00b's answer! That points out the right direction to go for me. I have implemented tap-focus for zbarViewController. Here is the idea:
You can add a custom view to zbarViewController by assigning a custom view to its cameraOverlayView. Then add a TapGestureRecagonizer to the custom view to catch the tap. Then, get the touch point and make the camera focus to the touch point. You would like possibly add a little rectangle around the touch point(that is what I did).
Here goes the code(assigning the custom view to cameraOverlayView:
UIView *view = [[UIView alloc] init];
UITapGestureRecognizer* tapScanner = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(focusAtPoint:)];
[view addGestureRecognizer:tapScanner];
reader.cameraOverlayView = view;
Then in selector 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];
}
}
}
}
}
I have added a white rectangle around the touch point, and then use selector dismissFocusRect to dismiss this rectangle. Here is the code:
- (void) dismissFocusRect{
for (UIView *subView in _reader.cameraOverlayView.subviews)
{
if (subView.tag == 99)
{
[subView removeFromSuperview];
}
}
}
I hope this could help!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With