Last active
January 4, 2023 01:46
-
-
Save Alex04/6976945 to your computer and use it in GitHub Desktop.
iPhone QR Code Scanning iOS7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AMScanViewController.h | |
// | |
// | |
// Created by Alexander Mack on 11.10.13. | |
// Copyright (c) 2013 ama-dev.com. All rights reserved. | |
// | |
#import <UIKit/UIKit.h> | |
#import <AVFoundation/AVFoundation.h> | |
@protocol AMScanViewControllerDelegate; | |
@interface AMScanViewController : UIViewController <AVCaptureMetadataOutputObjectsDelegate> | |
@property (nonatomic, weak) id<AMScanViewControllerDelegate> delegate; | |
@property (assign, nonatomic) BOOL touchToFocusEnabled; | |
- (BOOL) isCameraAvailable; | |
- (void) startScanning; | |
- (void) stopScanning; | |
- (void) setTorch:(BOOL) aStatus; | |
@end | |
@protocol AMScanViewControllerDelegate <NSObject> | |
@optional | |
- (void) scanViewController:(AMScanViewController *) aCtler didTapToFocusOnPoint:(CGPoint) aPoint; | |
- (void) scanViewController:(AMScanViewController *) aCtler didSuccessfullyScan:(NSString *) aScannedValue; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AMScanViewController.m | |
// | |
// | |
// Created by Alexander Mack on 11.10.13. | |
// Copyright (c) 2013 ama-dev.com. All rights reserved. | |
// | |
#import "AMScanViewController.h" | |
@interface AMScanViewController () | |
@property (strong, nonatomic) AVCaptureDevice* device; | |
@property (strong, nonatomic) AVCaptureDeviceInput* input; | |
@property (strong, nonatomic) AVCaptureMetadataOutput* output; | |
@property (strong, nonatomic) AVCaptureSession* session; | |
@property (strong, nonatomic) AVCaptureVideoPreviewLayer* preview; | |
@end | |
@implementation AMScanViewController | |
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil | |
{ | |
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; | |
if (self) { | |
} | |
return self; | |
} | |
- (void)viewWillAppear:(BOOL)animated; | |
{ | |
[super viewWillAppear:animated]; | |
if(![self isCameraAvailable]) { | |
[self setupNoCameraView]; | |
} | |
} | |
- (void) viewDidAppear:(BOOL)animated; | |
{ | |
[super viewDidAppear:animated]; | |
} | |
- (void)viewDidLoad | |
{ | |
[super viewDidLoad]; | |
if([self isCameraAvailable]) { | |
[self setupScanner]; | |
} | |
} | |
- (void)didReceiveMemoryWarning | |
{ | |
[super didReceiveMemoryWarning]; | |
// Dispose of any resources that can be recreated. | |
} | |
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)evt | |
{ | |
if(self.touchToFocusEnabled) { | |
UITouch *touch=[touches anyObject]; | |
CGPoint pt= [touch locationInView:self.view]; | |
[self focus:pt]; | |
} | |
} | |
#pragma mark - | |
#pragma mark NoCamAvailable | |
- (void) setupNoCameraView; | |
{ | |
UILabel *labelNoCam = [[UILabel alloc] init]; | |
labelNoCam.text = @"No Camera available"; | |
labelNoCam.textColor = [UIColor blackColor]; | |
[self.view addSubview:labelNoCam]; | |
[labelNoCam sizeToFit]; | |
labelNoCam.center = self.view.center; | |
} | |
- (NSUInteger)supportedInterfaceOrientations; | |
{ | |
return UIInterfaceOrientationMaskLandscape; | |
} | |
- (BOOL)shouldAutorotate; | |
{ | |
return (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation])); | |
} | |
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation; | |
{ | |
if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) { | |
AVCaptureConnection *con = self.preview.connection; | |
con.videoOrientation = AVCaptureVideoOrientationLandscapeRight; | |
} else { | |
AVCaptureConnection *con = self.preview.connection; | |
con.videoOrientation = AVCaptureVideoOrientationLandscapeLeft; | |
} | |
} | |
#pragma mark - | |
#pragma mark AVFoundationSetup | |
- (void) setupScanner; | |
{ | |
self.device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; | |
self.input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil]; | |
self.session = [[AVCaptureSession alloc] init]; | |
self.output = [[AVCaptureMetadataOutput alloc] init]; | |
[self.session addOutput:self.output]; | |
[self.session addInput:self.input]; | |
[self.output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; | |
self.output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode]; | |
self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session]; | |
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill; | |
self.preview.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); | |
AVCaptureConnection *con = self.preview.connection; | |
con.videoOrientation = AVCaptureVideoOrientationLandscapeLeft; | |
[self.view.layer insertSublayer:self.preview atIndex:0]; | |
} | |
#pragma mark - | |
#pragma mark Helper Methods | |
- (BOOL) isCameraAvailable; | |
{ | |
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; | |
return [videoDevices count] > 0; | |
} | |
- (void)startScanning; | |
{ | |
[self.session startRunning]; | |
} | |
- (void) stopScanning; | |
{ | |
[self.session stopRunning]; | |
} | |
- (void) setTorch:(BOOL) aStatus; | |
{ | |
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; | |
[device lockForConfiguration:nil]; | |
if ( [device hasTorch] ) { | |
if ( aStatus ) { | |
[device setTorchMode:AVCaptureTorchModeOn]; | |
} else { | |
[device setTorchMode:AVCaptureTorchModeOff]; | |
} | |
} | |
[device unlockForConfiguration]; | |
} | |
- (void) focus:(CGPoint) aPoint; | |
{ | |
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; | |
if([device isFocusPointOfInterestSupported] && | |
[device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) { | |
CGRect screenRect = [[UIScreen mainScreen] bounds]; | |
double screenWidth = screenRect.size.width; | |
double screenHeight = screenRect.size.height; | |
double focus_x = aPoint.x/screenWidth; | |
double focus_y = aPoint.y/screenHeight; | |
if([device lockForConfiguration:nil]) { | |
if([self.delegate respondsToSelector:@selector(scanViewController:didTapToFocusOnPoint:)]) { | |
[self.delegate scanViewController:self didTapToFocusOnPoint:aPoint]; | |
} | |
[device setFocusPointOfInterest:CGPointMake(focus_x,focus_y)]; | |
[device setFocusMode:AVCaptureFocusModeAutoFocus]; | |
if ([device isExposureModeSupported:AVCaptureExposureModeAutoExpose]){ | |
[device setExposureMode:AVCaptureExposureModeAutoExpose]; | |
} | |
[device unlockForConfiguration]; | |
} | |
} | |
} | |
#pragma mark - | |
#pragma mark AVCaptureMetadataOutputObjectsDelegate | |
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects | |
fromConnection:(AVCaptureConnection *)connection | |
{ | |
for(AVMetadataObject *current in metadataObjects) { | |
if([current isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) { | |
if([self.delegate respondsToSelector:@selector(scanViewController:didSuccessfullyScan:)]) { | |
NSString *scannedValue = [((AVMetadataMachineReadableCodeObject *) current) stringValue]; | |
[self.delegate scanViewController:self didSuccessfullyScan:scannedValue]; | |
} | |
} | |
} | |
} | |
@end |
Have you tried to change the device orientation? If memory serves me right the video orientation might be wrong without adjusting ist properly
Hi, can you please tell my how the adjust the camera orientation? It's not properly displaying and I use UIInterfaceOrientationPortrait doesn't work.
Can it scan data matrix code type? I tried but it can not.
Hi, I am getting this error "No known instance method for selector 'respondsToSelector:'
what may be the cause and how to fix this. Thank you
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also, I replaced line 125 in AMScanViewController.m with the following:
This ensures the preview is in the correct orientation if the app starts in landscape right.