ScanViewController.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. //
  2. // ScanViewController.m
  3. // Haishenghai-master
  4. //
  5. // Created by GG on 2019/1/3.
  6. // Copyright © 2019年 Haishenghai intelligence network technology. All rights reserved.
  7. //
  8. #import "ScanViewController.h"
  9. #import "EditLocationVC.h"
  10. #import "Header.h"
  11. #define KMainW [UIScreen mainScreen].bounds.size.width
  12. #define KMainH [UIScreen mainScreen].bounds.size.height
  13. @interface ScanViewController ()<AVCaptureMetadataOutputObjectsDelegate,UITextFieldDelegate>
  14. @end
  15. @implementation ScanViewController
  16. -(void)viewWillAppear:(BOOL)animated{
  17. [super viewWillAppear:YES];
  18. //开始扫描
  19. [_session startRunning];
  20. //添加定时器
  21. [self addTimer];
  22. //定时器开始
  23. self.timer.fireDate = [NSDate distantPast];
  24. }
  25. - (void)viewWillDisappear:(BOOL)animated
  26. {
  27. [super viewWillDisappear:animated];
  28. [self stopScanning];
  29. }
  30. - (void)initInfo
  31. {
  32. //背景色
  33. self.view.backgroundColor = [UIColor blackColor];
  34. //导航标题
  35. self.navigationItem.title = @"二维码/条形码";
  36. }
  37. - (void)viewDidLoad {
  38. [super viewDidLoad];
  39. //设置导航栏左侧按钮
  40. UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  41. [backBtn setImage:[UIImage imageNamed:@"hsh_return"] forState:UIControlStateNormal];
  42. backBtn.frame = CGRectMake(0, 0, 44, 44);
  43. [backBtn addTarget:self action:@selector(backClick) forControlEvents:UIControlEventTouchUpInside];
  44. backBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
  45. self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:backBtn];
  46. self.title = @"扫码";
  47. //初始化信息
  48. [self initInfo];
  49. //创建控件
  50. [self creatControl];
  51. //设置参数
  52. [self setupCamera];
  53. //添加定时器
  54. [self addTimer];
  55. }
  56. -(void)backClick{
  57. [self.navigationController popViewControllerAnimated:YES];
  58. }
  59. - (void)creatControl
  60. {
  61. CGFloat scanW = KMainW * 0.65;
  62. CGFloat padding = 10.0f;
  63. CGFloat labelH = 20.0f;
  64. CGFloat tabBarH = 64.0f;
  65. CGFloat cornerW = 26.0f;
  66. CGFloat marginX = (KMainW - scanW) * 0.5;
  67. CGFloat marginY = (KMainH - scanW - padding - labelH) * 0.5;
  68. //遮盖视图
  69. for (int i = 0; i < 4; i++) {
  70. UIView *cover = [[UIView alloc] initWithFrame:CGRectMake(0, (marginY + scanW) * i, KMainW, marginY + (padding + labelH) * i)];
  71. if (i == 2 || i == 3) {
  72. cover.frame = CGRectMake((marginX + scanW) * (i - 2), marginY, marginX, scanW);
  73. }
  74. cover.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
  75. [self.view addSubview:cover];
  76. }
  77. //扫描视图
  78. UIView *scanView = [[UIView alloc] initWithFrame:CGRectMake(marginX, marginY, scanW, scanW)];
  79. [self.view addSubview:scanView];
  80. //扫描线
  81. UIImageView *line = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, scanW, 2)];
  82. [self drawLineForImageView:line];
  83. [scanView addSubview:line];
  84. self.line = line;
  85. //边框
  86. UIView *borderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, scanW, scanW)];
  87. borderView.layer.borderColor = [[UIColor whiteColor] CGColor];
  88. borderView.layer.borderWidth = 1.0f;
  89. [scanView addSubview:borderView];
  90. //扫描视图四个角
  91. for (int i = 0; i < 4; i++) {
  92. CGFloat imgViewX = (scanW - cornerW) * (i % 2);
  93. CGFloat imgViewY = (scanW - cornerW) * (i / 2);
  94. UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(imgViewX, imgViewY, cornerW, cornerW)];
  95. if (i == 0 || i == 1) {
  96. imgView.transform = CGAffineTransformRotate(imgView.transform, M_PI_2 * i);
  97. }else {
  98. imgView.transform = CGAffineTransformRotate(imgView.transform, - M_PI_2 * (i - 1));
  99. }
  100. [self drawImageForImageView:imgView];
  101. [scanView addSubview:imgView];
  102. }
  103. //提示标签
  104. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(scanView.frame) + padding, KMainW, labelH)];
  105. label.text = @"将二维码/条形码放入框内,即可自动扫描";
  106. label.font = [UIFont systemFontOfSize:16.0f];
  107. label.textAlignment = NSTextAlignmentCenter;
  108. label.textColor = [UIColor whiteColor];
  109. [self.view addSubview:label];
  110. //选项栏
  111. UIView *tabBarView = [[UIView alloc] initWithFrame:CGRectMake(0, KMainH - tabBarH, KMainW, tabBarH)];
  112. tabBarView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8f];
  113. [self.view addSubview:tabBarView];
  114. //开启照明按钮
  115. UIButton *lightBtn = [[UIButton alloc] initWithFrame:CGRectMake(WIDTH/2-90, 0, 80, tabBarH)];
  116. lightBtn.titleLabel.font = [UIFont systemFontOfSize:16.0f];
  117. [lightBtn setImage:[UIImage imageNamed:@"hsh_hone_turnonthelight"] forState:UIControlStateNormal];
  118. // [lightBtn setTitle:@"开启照明" forState:UIControlStateNormal];
  119. // [lightBtn setTitle:@"关闭照明" forState:UIControlStateSelected];
  120. [lightBtn addTarget:self action:@selector(lightBtnOnClick:) forControlEvents:UIControlEventTouchUpInside];
  121. [tabBarView addSubview:lightBtn];
  122. //手动输入按钮
  123. UIButton *inputBtn = [[UIButton alloc] initWithFrame:CGRectMake(WIDTH/2+10, 0, 80, tabBarH)];
  124. inputBtn.titleLabel.font = [UIFont systemFontOfSize:16.0f];
  125. [inputBtn setImage:[UIImage imageNamed:@"hsh_hone_input"] forState:UIControlStateNormal];
  126. // [inputBtn setTitle:@"手动输入" forState:UIControlStateNormal];
  127. // [inputBtn setTitle:@"手动输入" forState:UIControlStateSelected];
  128. [inputBtn addTarget:self action:@selector(inputBtnOnClick:) forControlEvents:UIControlEventTouchUpInside];
  129. [tabBarView addSubview:inputBtn];
  130. }
  131. - (void)setupCamera
  132. {
  133. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  134. //初始化相机设备
  135. _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  136. //初始化输入流
  137. AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:nil];
  138. //初始化输出流
  139. AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
  140. //设置代理,主线程刷新
  141. [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  142. //初始化链接对象
  143. _session = [[AVCaptureSession alloc] init];
  144. //高质量采集率
  145. [_session setSessionPreset:AVCaptureSessionPresetHigh];
  146. if ([_session canAddInput:input]) [_session addInput:input];
  147. if ([_session canAddOutput:output]) [_session addOutput:output];
  148. //条码类型(二维码/条形码)
  149. output.metadataObjectTypes = [NSArray arrayWithObjects:AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode, nil];
  150. //更新界面
  151. dispatch_async(dispatch_get_main_queue(), ^{
  152. _preview = [AVCaptureVideoPreviewLayer layerWithSession:_session];
  153. _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
  154. _preview.frame = CGRectMake(0, 0, KMainW, KMainH);
  155. [self.view.layer insertSublayer:_preview atIndex:0];
  156. [_session startRunning];
  157. });
  158. });
  159. }
  160. - (void)addTimer
  161. {
  162. _distance = 0;
  163. self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
  164. [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
  165. }
  166. - (void)timerAction
  167. {
  168. if (_distance++ > KMainW * 0.65) _distance = 0;
  169. _line.frame = CGRectMake(0, _distance, KMainW * 0.65, 2);
  170. //添加动画
  171. }
  172. - (void)removeTimer
  173. {
  174. [_timer invalidate];
  175. _timer = nil;
  176. }
  177. //照明按钮点击事件
  178. - (void)lightBtnOnClick:(UIButton *)btn
  179. {
  180. //判断是否有闪光灯
  181. if (![_device hasTorch]) {
  182. [self showAlertWithTitle:@"当前设备没有闪光灯,无法开启照明功能" message:nil sureHandler:nil cancelHandler:nil];
  183. return;
  184. }
  185. btn.selected = !btn.selected;
  186. [_device lockForConfiguration:nil];
  187. if (btn.selected) {
  188. [_device setTorchMode:AVCaptureTorchModeOn];
  189. }else {
  190. [_device setTorchMode:AVCaptureTorchModeOff];
  191. }
  192. [_device unlockForConfiguration];
  193. }
  194. -(void)inputBtnOnClick:(UIButton *)inputBtn{
  195. //自定义消息提示框
  196. [self inputMessage];
  197. }
  198. #pragma mark - AVCaptureMetadataOutputObjectsDelegate
  199. - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
  200. {
  201. //扫描完成
  202. if ([metadataObjects count] > 0) {
  203. AVMetadataMachineReadableCodeObject * metadataObject = metadataObjects.firstObject;
  204. //得到解析到的结果
  205. NSString * stringValue;
  206. stringValue = metadataObject.stringValue;
  207. NSLog(@"%@",stringValue);
  208. //http://www.cccf.com.cn/lableFind.jsp?lableCode=30452AA09471AA
  209. //字符串截取
  210. NSArray *array = [stringValue componentsSeparatedByString:@"="];
  211. NSLog(@"array:%@",array);
  212. NSLog(@"array2:%@",[array objectAtIndex:1]);
  213. EditLocationVC *editVc = [[EditLocationVC alloc]init];
  214. editVc.deveceNumber = [array objectAtIndex:1];
  215. editVc.deveceName = self.deveceName;
  216. [self.navigationController pushViewController:editVc animated:YES];
  217. //在这里播放音效文件
  218. [self playSound];
  219. //停止扫描
  220. [self stopScanning];
  221. // //显示结果跳转
  222. }
  223. }
  224. - (void)stopScanning
  225. {
  226. [_session stopRunning];
  227. _session = nil;
  228. [_preview removeFromSuperlayer];
  229. [self removeTimer];
  230. }
  231. ////提示弹窗
  232. - (void)showAlertWithTitle:(NSString *)title message:(NSString *)message sureHandler:(void (^)())sureHandler cancelHandler:(void (^)())cancelHandler
  233. {
  234. UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
  235. UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:sureHandler];
  236. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:cancelHandler];
  237. [alertController addAction:sureAction];
  238. [alertController addAction:cancelAction];
  239. [self presentViewController:alertController animated:YES completion:nil];
  240. }
  241. //绘制角图片
  242. - (void)drawImageForImageView:(UIImageView *)imageView
  243. {
  244. UIGraphicsBeginImageContext(imageView.bounds.size);
  245. //获取上下文
  246. CGContextRef context = UIGraphicsGetCurrentContext();
  247. //设置线条宽度
  248. CGContextSetLineWidth(context, 6.0f);
  249. //设置颜色
  250. CGContextSetStrokeColorWithColor(context, [[UIColor greenColor] CGColor]);
  251. //路径
  252. CGContextBeginPath(context);
  253. //设置起点坐标
  254. CGContextMoveToPoint(context, 0, imageView.bounds.size.height);
  255. //设置下一个点坐标
  256. CGContextAddLineToPoint(context, 0, 0);
  257. CGContextAddLineToPoint(context, imageView.bounds.size.width, 0);
  258. //渲染,连接起点和下一个坐标点
  259. CGContextStrokePath(context);
  260. imageView.image = UIGraphicsGetImageFromCurrentImageContext();
  261. UIGraphicsEndImageContext();
  262. }
  263. //绘制线图片
  264. - (void)drawLineForImageView:(UIImageView *)imageView
  265. {
  266. CGSize size = imageView.bounds.size;
  267. UIGraphicsBeginImageContext(size);
  268. //获取上下文
  269. CGContextRef context = UIGraphicsGetCurrentContext();
  270. //创建一个颜色空间
  271. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  272. //设置开始颜色
  273. const CGFloat *startColorComponents = CGColorGetComponents([[UIColor greenColor] CGColor]);
  274. //设置结束颜色
  275. const CGFloat *endColorComponents = CGColorGetComponents([[UIColor whiteColor] CGColor]);
  276. //颜色分量的强度值数组
  277. CGFloat components[8] = {startColorComponents[0], startColorComponents[1], startColorComponents[2], startColorComponents[3], endColorComponents[0], endColorComponents[1], endColorComponents[2], endColorComponents[3]
  278. };
  279. //渐变系数数组
  280. CGFloat locations[] = {0.0, 1.0};
  281. //创建渐变对象
  282. CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 2);
  283. //绘制渐变
  284. CGContextDrawRadialGradient(context, gradient, CGPointMake(size.width * 0.5, size.height * 0.5), size.width * 0.25, CGPointMake(size.width * 0.5, size.height * 0.5), size.width * 0.5, kCGGradientDrawsBeforeStartLocation);
  285. //释放
  286. CGColorSpaceRelease(colorSpace);
  287. CGGradientRelease(gradient);
  288. imageView.image = UIGraphicsGetImageFromCurrentImageContext();
  289. UIGraphicsEndImageContext();
  290. }
  291. //扫描成功之后提示音的设置(播放自定义音效文件方法)
  292. -(void)playSound{
  293. //定义一个SystemSoundID
  294. SystemSoundID soundID = 1000;//具体参数详情下面贴出来
  295. //播放声音
  296. AudioServicesPlaySystemSound(soundID);
  297. }
  298. - (void)didReceiveMemoryWarning {
  299. [super didReceiveMemoryWarning];
  300. // Dispose of any resources that can be recreated.
  301. }
  302. /*
  303. #pragma mark - Navigation
  304. // In a storyboard-based application, you will often want to do a little preparation before navigation
  305. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  306. // Get the new view controller using [segue destinationViewController].
  307. // Pass the selected object to the new view controller.
  308. }
  309. */
  310. #pragma mark-----input---
  311. -(void)inputMessage{
  312. UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"输入设备编号" message:nil preferredStyle:UIAlertControllerStyleAlert];
  313. //取消按钮
  314. [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  315. }]];
  316. //确定按钮
  317. [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  318. EditLocationVC *editVc = [[EditLocationVC alloc]init];
  319. UITextField *nameTF = alert.textFields.firstObject;
  320. editVc.deveceNumber =nameTF.text;
  321. editVc.deveceName = self.deveceName;
  322. editVc.typeID = self.typeId;
  323. [self.navigationController pushViewController:editVc animated:YES];
  324. }]];
  325. //定义输入框
  326. [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
  327. textField.delegate =self;
  328. textField.placeholder = @"请手动输入编号";
  329. }];
  330. [self presentViewController:alert animated:YES completion:nil];
  331. }
  332. @end