OPQRCodeViewController.m 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. //
  2. // OPQRCodeViewController.m
  3. // OneStationPlatform
  4. //
  5. // Created by SonWa on 15/7/15.
  6. // Copyright (c) 2015年 SonWa. All rights reserved.
  7. //
  8. #import "OPQRCodeViewController.h"
  9. #import <AudioToolbox/AudioToolbox.h>
  10. #import <AVFoundation/AVFoundation.h>
  11. @interface OPQRCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate> {
  12. int num;
  13. BOOL upOrdown;
  14. NSTimer * timer;
  15. }
  16. @property (strong,nonatomic)AVCaptureDevice * device;
  17. @property (strong,nonatomic)AVCaptureDeviceInput * input;
  18. @property (strong,nonatomic)AVCaptureMetadataOutput * output;
  19. @property (strong,nonatomic)AVCaptureSession * session;
  20. @property (strong,nonatomic)AVCaptureVideoPreviewLayer * preview;
  21. @property (nonatomic, retain) UIImageView * line;
  22. @property (nonatomic, strong) NSString *bundlePath;
  23. @end
  24. @implementation OPQRCodeViewController
  25. #define ishasNavBar self.navigationController && self.navigationController.navigationBar.hidden == NO
  26. #define scanBoxX (SCREEN_WIDTH - width)*0.5
  27. #define scanBoxY (SCREEN_HEIGHT - height)*0.5
  28. //#define scanBoxY ishasNavBar ? (SCREEN_HEIGHT - height)*0.5-64 : (SCREEN_HEIGHT - height)*0.5
  29. -(NSString *)bundlePath
  30. {
  31. if (_bundlePath == nil) {
  32. //获取路径
  33. NSString * path = [[NSBundle mainBundle] pathForResource:@"RDHomeKit" ofType:@"bundle"];
  34. _bundlePath = [path stringByAppendingPathComponent:@"images"];
  35. }
  36. return _bundlePath;
  37. }
  38. - (BOOL)p_verfilyVideoUseStatus {
  39. BOOL enable = YES;
  40. AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  41. if (status == AVAuthorizationStatusRestricted || status == AVAuthorizationStatusDenied) {
  42. enable = NO;
  43. UIAlertController * alertC = [UIAlertController alertControllerWithTitle:@"摄像头访问受限"
  44. message:@"请到手机设置里允许APP使用摄像头"
  45. preferredStyle:UIAlertControllerStyleAlert];
  46. [self presentViewController:alertC animated:YES completion:nil];
  47. RDS_WEAKSELF(weakSelf)
  48. UIAlertAction * action = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
  49. [weakSelf dismissViewControllerAnimated:YES completion:nil];
  50. [weakSelf.navigationController popViewControllerAnimated:YES];
  51. }];
  52. [alertC addAction:action];
  53. }
  54. return enable;
  55. }
  56. - (void)p_setupCameraWithVerify {
  57. if ([self p_verfilyVideoUseStatus]) {
  58. [self setupCamera];
  59. }
  60. }
  61. - (void)viewDidLoad {
  62. [super viewDidLoad];
  63. // @"扫一扫";
  64. self.title = @"";
  65. self.view.backgroundColor = [UIColor blackColor];
  66. CGFloat width = 0.8*SCREEN_WIDTH;
  67. CGFloat height = width;
  68. CGFloat x = scanBoxX;
  69. CGFloat y = scanBoxY+_topOffset;
  70. upOrdown = NO;
  71. num =0;
  72. _line = [[UIImageView alloc] initWithFrame:CGRectMake(x, y, width, 2)];
  73. _line.image = [UIImage imageWithContentsOfFile:[self.bundlePath stringByAppendingPathComponent:@"QRCodeScanLine.png"]];
  74. [self.view addSubview:_line];
  75. timer = [NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(animation1) userInfo:nil repeats:YES];
  76. [self performSelectorOnMainThread:@selector(p_setupCameraWithVerify) withObject:nil waitUntilDone:NO];
  77. // 添加背景view
  78. CGFloat topSize = scanBoxY+_topOffset;
  79. CGFloat leftSize = scanBoxX;
  80. UIView *upView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, topSize)];
  81. upView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
  82. [self.view addSubview:upView];
  83. UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, topSize, leftSize, height)];
  84. leftView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
  85. [self.view addSubview:leftView];
  86. UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-leftSize, topSize, leftSize, height)];
  87. rightView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
  88. [self.view addSubview:rightView];
  89. UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0,topSize+height, SCREEN_WIDTH, SCREEN_HEIGHT-(topSize+height))];
  90. bottomView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
  91. [self.view addSubview:bottomView];
  92. UIImageView *leftTopBorder = [[UIImageView alloc]initWithImage:[UIImage imageWithContentsOfFile:[self.bundlePath stringByAppendingPathComponent:@"ScanQR1.png"]]];
  93. leftTopBorder.frame = CGRectMake(leftSize, topSize, 16, 16);
  94. [self.view addSubview:leftTopBorder];
  95. UIImageView *rightTopBorder = [[UIImageView alloc]initWithImage:[UIImage imageWithContentsOfFile:[self.bundlePath stringByAppendingPathComponent:@"ScanQR2"]]];
  96. rightTopBorder.frame = CGRectMake(SCREEN_WIDTH-leftSize-16, topSize, 16, 16);
  97. [self.view addSubview:rightTopBorder];
  98. UIImageView *leftBottomBorder = [[UIImageView alloc]initWithImage:[UIImage imageWithContentsOfFile:[self.bundlePath stringByAppendingPathComponent:@"ScanQR3"]]];
  99. leftBottomBorder.frame = CGRectMake(leftSize, topSize+height-16, 16, 16);
  100. [self.view addSubview:leftBottomBorder];
  101. UIImageView *rightBottomBorder = [[UIImageView alloc]initWithImage:[UIImage imageWithContentsOfFile:[self.bundlePath stringByAppendingPathComponent:@"ScanQR4"]]];
  102. rightBottomBorder.frame = CGRectMake(SCREEN_WIDTH-leftSize-16, topSize+height-16, 16, 16);
  103. [self.view addSubview:rightBottomBorder];
  104. UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, topSize+height+20, SCREEN_WIDTH, 14)];
  105. [self.view addSubview:label];
  106. //[label setText:@"将二维码放入框内,即可自动扫描"];
  107. [label setFont:systemFont(14)];
  108. [label setTextColor:[UIColor whiteColor]];
  109. [label setTextAlignment:NSTextAlignmentCenter];
  110. }
  111. - (void)viewWillAppear:(BOOL)animated {
  112. [super viewWillAppear:animated];
  113. [_session startRunning];
  114. }
  115. -(void)animation1
  116. {
  117. CGFloat width = 0.8*SCREEN_WIDTH;
  118. CGFloat height = width;
  119. CGFloat x = scanBoxX;
  120. CGFloat y = scanBoxY+_topOffset;
  121. if (upOrdown == NO) {
  122. num ++;
  123. _line.frame = CGRectMake(x, y+2*num, width, 2);
  124. if (2*num >= height) {
  125. upOrdown = YES;
  126. }
  127. }
  128. else {
  129. num --;
  130. _line.frame = CGRectMake(x, y+2*num, width, 2);
  131. if (num == 0) {
  132. upOrdown = NO;
  133. }
  134. }
  135. }
  136. -(void)backAction
  137. {
  138. // [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
  139. [self setNeedsStatusBarAppearanceUpdate];
  140. [_session stopRunning];
  141. [self dismissViewControllerAnimated:YES completion:^{
  142. [self->timer invalidate];
  143. }];
  144. }
  145. -(void)viewWillDisappear:(BOOL)animated
  146. {
  147. [super viewWillDisappear:animated];
  148. [_session stopRunning];
  149. [timer invalidate];
  150. //[timer setFireDate:[NSDate distantFuture]]; //暂停
  151. }
  152. - (void)setupCamera
  153. {
  154. // Device
  155. _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  156. // Input
  157. _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
  158. // Output
  159. _output = [[AVCaptureMetadataOutput alloc]init];
  160. CGFloat width = 0.8*SCREEN_WIDTH;
  161. CGFloat height = width;
  162. CGFloat x = scanBoxX;
  163. CGFloat y = scanBoxY+_topOffset;
  164. [_output setRectOfInterest:CGRectMake(y/SCREEN_HEIGHT,x/SCREEN_WIDTH,width/SCREEN_HEIGHT,height/SCREEN_WIDTH)];
  165. [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  166. // Session
  167. _session = [[AVCaptureSession alloc]init];
  168. [_session setSessionPreset:AVCaptureSessionPresetHigh];
  169. if ([_session canAddInput:self.input])
  170. {
  171. [_session addInput:self.input];
  172. }
  173. if ([_session canAddOutput:self.output])
  174. {
  175. [_session addOutput:self.output];
  176. }
  177. // 条码类型 AVMetadataObjectTypeQRCode
  178. _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
  179. _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
  180. _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
  181. _preview.frame =CGRectMake(0, 0, FULL_WIDTH, SCREEN_HEIGHT);
  182. [self.view.layer insertSublayer:_preview atIndex:0];
  183. // Start
  184. [timer setFireDate:[NSDate distantPast]];
  185. [_session startRunning];
  186. }
  187. #pragma mark AVCaptureMetadataOutputObjectsDelegate
  188. - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
  189. {
  190. NSString *stringValue;
  191. if ([metadataObjects count] >0)
  192. {
  193. AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
  194. stringValue = metadataObject.stringValue;
  195. }
  196. [_session stopRunning];
  197. [timer invalidate];
  198. //[timer setFireDate:[NSDate distantFuture]]; //暂停
  199. if (_delegate && [_delegate respondsToSelector:@selector(rdy_didFinishPickingMediaWithInfo:)]) {
  200. [_delegate rdy_didFinishPickingMediaWithInfo:stringValue];
  201. }
  202. [self.navigationController popViewControllerAnimated:YES];
  203. }
  204. - (void)didReceiveMemoryWarning {
  205. [super didReceiveMemoryWarning];
  206. // Dispose of any resources that can be recreated.
  207. }
  208. /*
  209. #pragma mark - Navigation
  210. // In a storyboard-based application, you will often want to do a little preparation before navigation
  211. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  212. // Get the new view controller using [segue destinationViewController].
  213. // Pass the selected object to the new view controller.
  214. }
  215. */
  216. @end