OPQRCodeViewController.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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, 5)];
  73. _line.image = [UIImage imageNamed:@"QRCodeScanLine"];
  74. [self.view addSubview:_line];
  75. timer = [NSTimer scheduledTimerWithTimeInterval:0.01 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. UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  111. [backBtn setBackgroundImage:[UIImage imageNamed:@"icon_back_white"] forState:UIControlStateNormal];
  112. [backBtn addTarget:self action:@selector(backAction) forControlEvents:UIControlEventTouchUpInside];
  113. [self.view addSubview:backBtn];
  114. [backBtn mas_makeConstraints:^(MASConstraintMaker *make) {
  115. make.top.equalTo(@60);
  116. make.left.equalTo(@20);
  117. make.height.equalTo(@20);
  118. make.width.equalTo(@20);
  119. }];
  120. }
  121. - (void)viewWillAppear:(BOOL)animated {
  122. [super viewWillAppear:animated];
  123. [_session startRunning];
  124. }
  125. -(void)animation1
  126. {
  127. CGFloat width = 0.8*SCREEN_WIDTH;
  128. CGFloat height = width;
  129. CGFloat x = scanBoxX;
  130. CGFloat y = scanBoxY+_topOffset;
  131. if (upOrdown == NO) {
  132. num ++;
  133. _line.frame = CGRectMake(x, y+2*num, width, 5);
  134. if (2*num >= height) {
  135. upOrdown = YES;
  136. }
  137. }else {
  138. num --;
  139. _line.frame = CGRectMake(x, y+2*num, width, 5);
  140. if (num == 0) {
  141. upOrdown = NO;
  142. }
  143. }
  144. }
  145. -(void)backAction
  146. {
  147. // [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
  148. [self setNeedsStatusBarAppearanceUpdate];
  149. [_session stopRunning];
  150. [self dismissViewControllerAnimated:YES completion:^{
  151. [self->timer invalidate];
  152. }];
  153. }
  154. -(void)viewWillDisappear:(BOOL)animated
  155. {
  156. [super viewWillDisappear:animated];
  157. [_session stopRunning];
  158. [timer invalidate];
  159. //[timer setFireDate:[NSDate distantFuture]]; //暂停
  160. }
  161. - (void)setupCamera
  162. {
  163. // Device
  164. _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  165. // Input
  166. _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
  167. // Output
  168. _output = [[AVCaptureMetadataOutput alloc]init];
  169. CGFloat width = 0.8*SCREEN_WIDTH;
  170. CGFloat height = width;
  171. CGFloat x = scanBoxX;
  172. CGFloat y = scanBoxY+_topOffset;
  173. [_output setRectOfInterest:CGRectMake(y/SCREEN_HEIGHT,x/SCREEN_WIDTH,width/SCREEN_HEIGHT,height/SCREEN_WIDTH)];
  174. [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  175. // Session
  176. _session = [[AVCaptureSession alloc]init];
  177. [_session setSessionPreset:AVCaptureSessionPresetHigh];
  178. if ([_session canAddInput:self.input])
  179. {
  180. [_session addInput:self.input];
  181. }
  182. if ([_session canAddOutput:self.output])
  183. {
  184. [_session addOutput:self.output];
  185. }
  186. // 条码类型 AVMetadataObjectTypeQRCode
  187. _output.metadataObjectTypes =@[AVMetadataObjectTypeQRCode];
  188. _preview =[AVCaptureVideoPreviewLayer layerWithSession:self.session];
  189. _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
  190. _preview.frame =CGRectMake(0, 0, FULL_WIDTH, SCREEN_HEIGHT);
  191. [self.view.layer insertSublayer:_preview atIndex:0];
  192. // Start
  193. [timer setFireDate:[NSDate distantPast]];
  194. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  195. [self->_session startRunning];
  196. });
  197. }
  198. #pragma mark AVCaptureMetadataOutputObjectsDelegate
  199. - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
  200. {
  201. NSString *stringValue;
  202. if ([metadataObjects count] >0)
  203. {
  204. AVMetadataMachineReadableCodeObject * metadataObject = [metadataObjects objectAtIndex:0];
  205. stringValue = metadataObject.stringValue;
  206. }
  207. [_session stopRunning];
  208. [timer invalidate];
  209. //[timer setFireDate:[NSDate distantFuture]]; //暂停
  210. if (_delegate && [_delegate respondsToSelector:@selector(rdy_didFinishPickingMediaWithInfo:)]) {
  211. [_delegate rdy_didFinishPickingMediaWithInfo:stringValue];
  212. }
  213. [self dismissViewControllerAnimated:YES completion:nil];
  214. // [self.navigationController popViewControllerAnimated:YES];
  215. }
  216. - (void)didReceiveMemoryWarning {
  217. [super didReceiveMemoryWarning];
  218. // Dispose of any resources that can be recreated.
  219. }
  220. /*
  221. #pragma mark - Navigation
  222. // In a storyboard-based application, you will often want to do a little preparation before navigation
  223. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  224. // Get the new view controller using [segue destinationViewController].
  225. // Pass the selected object to the new view controller.
  226. }
  227. */
  228. @end