ScanVC.m 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. //
  2. // ScanVC.m
  3. // jiaPei
  4. //
  5. // Created by apple on 16/4/19.
  6. // Copyright © 2016年 JCZ. All rights reserved.
  7. //
  8. #import "ScanVC.h"
  9. #import <AVFoundation/AVFoundation.h>
  10. #import "DES3Util.h"
  11. #import "Tools.h"
  12. #define KWidth (kSize.width/2.0 + 30)
  13. @interface ScanVC ()<AVCaptureMetadataOutputObjectsDelegate>
  14. {
  15. BOOL isDown;
  16. NSTimer *timer;
  17. NSInteger num;
  18. UIImageView *scanBackground;
  19. UIImageView *line;
  20. AVCaptureDevice *device;
  21. AVCaptureSession *session;
  22. AVCaptureDeviceInput *input;
  23. AVCaptureMetadataOutput *output;
  24. AVCaptureVideoPreviewLayer *preview;
  25. NSInteger order;
  26. NSString *dataString;
  27. }
  28. @end
  29. @implementation ScanVC
  30. - (void)viewDidLoad {
  31. [super viewDidLoad];
  32. self.view.backgroundColor = backGroundColor;
  33. self.title = @"二维码扫描";
  34. [self configNavigationBar];
  35. scanBackground = [[UIImageView alloc] initWithFrame:CGRectMake((kSize.width - KWidth)/2.0, (kSize.height - KWidth)/2.0 - kNavOffSet, KWidth, KWidth)];
  36. scanBackground.image = [[UIImage imageNamed:@"scanBackground.png"] tint:RQ_MAIN_COLOR];
  37. [self.view addSubview:scanBackground];
  38. line = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetMinX(scanBackground.frame)+5, CGRectGetMinY(scanBackground.frame)+5, KWidth-10,2)];
  39. line.image = [[UIImage imageNamed:@"scanLine.png"] tint:RQ_MAIN_COLOR];
  40. [self.view addSubview:line];
  41. [self setOverView];
  42. [self initScan];
  43. order = 0;
  44. isDown = YES;
  45. num = 0;
  46. timer = [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:@selector(timeRunToAnimation) userInfo:nil repeats:YES];
  47. }
  48. -(void)viewWillAppear:(BOOL)animated
  49. {
  50. [super viewWillAppear:animated];
  51. num = 0; //让先从最上面开始扫描
  52. if (timer) {
  53. [timer setFireDate:[NSDate distantPast]];
  54. }
  55. if (session && ![session isRunning]) {
  56. [session startRunning];
  57. }
  58. }
  59. -(void)viewWillDisappear:(BOOL)animated
  60. {
  61. [super viewWillDisappear:animated];
  62. if (timer) {
  63. [timer setFireDate:[NSDate distantFuture]];
  64. }
  65. if (session && [session isRunning]) {
  66. [session stopRunning];
  67. }
  68. }
  69. - (void)timeRunToAnimation {
  70. if (isDown) {
  71. num ++;
  72. if (num > (KWidth-10)/2.0) {
  73. isDown = NO;
  74. }
  75. }else{
  76. num --;
  77. if (num == 0) {
  78. isDown = YES;
  79. }
  80. }
  81. line.frame = CGRectMake(CGRectGetMinX(scanBackground.frame)+5, CGRectGetMinY(scanBackground.frame)+5 + num*2, KWidth-10,2);
  82. }
  83. //二维码操作
  84. -(void)initScan
  85. {
  86. NSString *mediaType = AVMediaTypeVideo;
  87. AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
  88. if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) {
  89. [self.navigationController popViewControllerAnimated:YES];
  90. [RQ_SHARE_FUNCTION showAlertWithTitle:@"温馨提示" message:@"请在iPhone的“设置”-“隐私”-“相机”功能中,找到“极速驾培”打开相机访问权限" alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"取消" otherButtonTitles:@[@"确定"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
  91. if (selectedOtherButtonIndex == 0) {
  92. NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
  93. if ([[UIApplication sharedApplication] canOpenURL:url]) {
  94. [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
  95. }
  96. }
  97. }];
  98. return;
  99. }
  100. //获取设备
  101. device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  102. //输入流
  103. input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
  104. //输出流
  105. output = [[AVCaptureMetadataOutput alloc] init];
  106. //设置代理
  107. //(kSize.width - KWidth)/2.0, (kSize.height - KWidth)/2.0, KWidth, KWidth)
  108. //这里添加一点 这样就很容易扫到码了
  109. CGRect rect = scanBackground.frame;
  110. rect.origin.x = (kSize.width - KWidth - 80)/2.0;
  111. rect.origin.y = (kSize.height - KWidth - 80)/2.0;
  112. rect.size.width = rect.size.height = KWidth + 80;
  113. [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  114. output.rectOfInterest =[self rectOfInterestByScanViewRect:rect];
  115. //NSLog(@"%@",output.rectOfInterest);
  116. //起连接作用的回执
  117. session = [[AVCaptureSession alloc] init];
  118. [session setSessionPreset:AVCaptureSessionPresetHigh];
  119. if ([session canAddInput:input]){
  120. [session addInput:input];
  121. }
  122. if ([session canAddOutput:output]){
  123. [session addOutput:output];
  124. }
  125. //指定output所能扫描的类型
  126. output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode];
  127. //界面
  128. preview = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
  129. preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
  130. preview.frame = self.view.bounds;
  131. [self.view.layer insertSublayer:preview atIndex:0];
  132. [self.view bringSubviewToFront:scanBackground];
  133. //开始扫描
  134. [session startRunning];
  135. }
  136. //扫描到的信息通过output的协议方法返回
  137. - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
  138. {
  139. if (metadataObjects.count > 0)
  140. {
  141. AVMetadataMachineReadableCodeObject *object = [metadataObjects firstObject];
  142. //session关闭
  143. [session stopRunning];
  144. [timer setFireDate:[NSDate distantFuture]];
  145. //需要我们对接的二维码抬头
  146. if ([object.stringValue containsString:@"#DECODE#"] && object.stringValue.length > 8) {
  147. BOOL SP_IS_MNQisTure = NO;
  148. for (ParamsItem *item in RQ_USER_MANAGER.currentUser.params) {
  149. if ([item.KEY isEqualToString:@"SP_IS_MNQ"]) {
  150. if ([item.VALUE isEqualToString:@"1"]) {
  151. SP_IS_MNQisTure = YES;
  152. }
  153. }
  154. }
  155. //程序内某些验证
  156. NSString *testString = [DES3Util decrypt:[object.stringValue substringFromIndex:8]];
  157. NSArray *scanArray = [testString componentsSeparatedByString:@";"];
  158. /* 是APP的二维码*/
  159. if ([[scanArray firstObject] isEqualToString:@"#JSDTMO#"]) {
  160. //二维码是否过期
  161. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  162. formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
  163. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  164. NSDate *scanDate = [formatter dateFromString:[scanArray lastObject]];
  165. NSTimeInterval time = [scanDate timeIntervalSinceNow];
  166. if (time < 0) {
  167. ShowMsg(@"二维码信息已过期");
  168. [session startRunning];
  169. [timer setFireDate:[NSDate distantPast]];
  170. return;
  171. }
  172. /*
  173. 非计划实操计时
  174. 标识符 type 教练outID 教练姓名 价格 科目 教练手机号码 终端设备号 有效时间
  175. */
  176. if ([scanArray[1] isEqualToString:@"signIn"]) {
  177. if(self.type == 2){
  178. [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
  179. return;
  180. }
  181. order = 1;
  182. dataString = [[testString componentsSeparatedByString:@"signIn;"] lastObject];
  183. [self alertShowWithString:[NSString stringWithFormat:@"当前所选为%@教练,是否开始实操练习?",scanArray[3]]];
  184. return;
  185. }
  186. /*
  187. 计划实操计时
  188. 标识符 type 教练outID 教练姓名 学生证号 预约ID 电话号码 终端设备号 有效时间
  189. */
  190. if ([scanArray[1] isEqualToString:@"planSignIn"]) {
  191. if(self.type == 2){
  192. [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
  193. return;
  194. }
  195. if (![scanArray[4] isEqualToString:RQ_USER_MANAGER.currentUser._id]) {
  196. ShowMsg(@"当前准教学员信息与本人不符,请核对二维码");
  197. [Tools playAudioWithString:@"当前准教学员信息与本人不符,请核对二维码"];
  198. [session startRunning];
  199. [timer setFireDate:[NSDate distantPast]];
  200. return;
  201. }
  202. order = 2;
  203. dataString = [[testString componentsSeparatedByString:@"planSignIn;"] lastObject];
  204. [self alertShowWithString:[NSString stringWithFormat:@"当前所选为%@教练,是否开始实操练习?",scanArray[3]]];
  205. return;
  206. }
  207. /*
  208. 实操结束计时
  209. 标识符 type 教练outID 学生身份证明 有效时间
  210. */
  211. if ([scanArray[1] isEqualToString:@"signOut"] || [scanArray[1] isEqualToString:@"planSignOut"]) {
  212. if(self.type == 2){
  213. [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
  214. return;
  215. }
  216. NSDictionary *gatherTrainDic;
  217. NSString *filePath = [Tools getPathWithFileName:@"gatherTrainDic.plist"];
  218. if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
  219. gatherTrainDic = [NSMutableDictionary dictionaryWithContentsOfFile:filePath];
  220. }
  221. if ([gatherTrainDic[@"isPlan"] isEqualToString:@"1"] && [scanArray[1] isEqualToString:@"signOut"]) {
  222. ShowMsg(@"请选择正确结束方式!");
  223. return;
  224. }
  225. if ([gatherTrainDic[@"isPlan"] isEqualToString:@"2"] && [scanArray[1] isEqualToString:@"planSignOut"]) {
  226. ShowMsg(@"请选择正确结束方式!");
  227. return;
  228. }
  229. NSString *identString = RQ_USER_MANAGER.currentUser.outId;
  230. if ([scanArray[1] isEqualToString:@"planSignOut"]) {
  231. identString = RQ_USER_MANAGER.currentUser._id;
  232. }
  233. if (![scanArray[3] isEqualToString:identString]) {
  234. ShowMsg(@"当前准教学员信息与本人不符,请核对二维码");
  235. [Tools playAudioWithString:@"当前准教学员信息与本人不符,请核对二维码"];
  236. [session startRunning];
  237. [timer setFireDate:[NSDate distantPast]];
  238. return;
  239. }
  240. order = 3;
  241. if ([scanArray[1] isEqualToString:@"signOut"]) {
  242. dataString = [[testString componentsSeparatedByString:@"signOut;"] lastObject];
  243. }else{
  244. dataString = [[testString componentsSeparatedByString:@"planSignOut;"] lastObject];
  245. }
  246. [self alertShowWithString:[NSString stringWithFormat:@"结束实操练习?"]];
  247. return;
  248. }
  249. /*
  250. 模拟开始计时
  251. 标识符 type 教练outID 教练名字 教练经度 教练纬度 有效时间
  252. */
  253. if ([scanArray[1] isEqualToString:@"imitSignIn"]) {
  254. if (self.type == 1) {
  255. [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"实操计时\"二维码"];
  256. return;
  257. }
  258. if (SP_IS_MNQisTure) {
  259. ShowMsg(@"请使用模拟机设备计时");
  260. [session startRunning];
  261. [timer setFireDate:[NSDate distantPast]];
  262. return;
  263. }
  264. order = 4;
  265. dataString = [[testString componentsSeparatedByString:@"imitSignIn;"] lastObject];
  266. [self alertShowWithString:[NSString stringWithFormat:@"当前所选为%@教练,是否开始模拟练习?",scanArray[3]]];
  267. return;
  268. }
  269. /*模拟设备(非app二维码)(不包含#JSDTMO#)*/
  270. }else if ([[scanArray firstObject] isEqualToString:@"#MNQ#"]){
  271. if (self.type == 1) {
  272. [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"实操计时\"二维码"];
  273. return;
  274. }
  275. /*
  276. 模拟开始 模拟设备打模拟学时
  277. #MNQ#;序列号(devSn);动态码(dynamicCode);签到/签退类型(1签到 3签退)
  278. */
  279. if (!SP_IS_MNQisTure) {
  280. ShowMsg(@"暂不能使用模拟起设备");
  281. [session startRunning];
  282. [timer setFireDate:[NSDate distantPast]];
  283. return;
  284. }
  285. order = 5;
  286. dataString = [[testString componentsSeparatedByString:@"#MNQ#;"] lastObject];
  287. NSString *showString = @"正在进行模拟计时签到,是否开始模拟练习?";
  288. if ([[NSString stringWithFormat:@"%@",[scanArray lastObject]] isEqualToString:@"2"]) {
  289. showString = @"签退";
  290. }
  291. [self alertShowWithString:showString];
  292. return;
  293. }else{
  294. //包含#decode# 非@"#JSDTMO#" 非#MNQ#
  295. }
  296. }
  297. /*无须我们对接的二维码(不包含#DECODE#)*/
  298. if (self.type == 1) {
  299. [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"实操计时\"二维码"];
  300. }else if(self.type == 2){
  301. [self showMsgByAlertControllerWithString:@"二维码类型错误,请扫描\"模拟计时\"二维码"];
  302. }
  303. //判断是否进入进某网址
  304. // if ([object.stringValue containsString:@".com"] || [object.stringValue containsString:@".cn"]) {
  305. // [[UIApplication sharedApplication] openURL:[NSURL URLWithString:object.stringValue]];
  306. // [self.navigationController popViewControllerAnimated:YES];
  307. // return;
  308. // }
  309. //扫码网页登录用
  310. // order = -1;
  311. // dataString = object.stringValue;
  312. // [self alertShowWithString:@"是否允许登录公众平台?"];
  313. }
  314. }
  315. -(void)showMsgByAlertControllerWithString:(NSString *)str {
  316. [RQ_SHARE_FUNCTION showAlertWithTitle:@"提示" message:str alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"重新扫描" otherButtonTitles:@[@"退出"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
  317. switch (selectedOtherButtonIndex) {
  318. case NSNotFound: {
  319. //取消就重新打开扫描
  320. [session startRunning];
  321. [timer setFireDate:[NSDate distantPast]];
  322. break;
  323. }
  324. case 0: {
  325. [self.navigationController popViewControllerAnimated:YES];
  326. break;
  327. }
  328. default:
  329. break;
  330. }
  331. }];
  332. // UIAlertController *alertFind = [UIAlertController alertControllerWithTitle:@"提示" message:str preferredStyle:UIAlertControllerStyleAlert];
  333. //
  334. // [alertFind addAction:[UIAlertAction actionWithTitle:@"重新扫描" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
  335. // //取消就重新打开扫描
  336. // [session startRunning];
  337. // [timer setFireDate:[NSDate distantPast]];
  338. // }]];
  339. // [alertFind addAction:[UIAlertAction actionWithTitle:@"退出" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
  340. // [self.navigationController popViewControllerAnimated:YES];
  341. // }]];
  342. // [self presentViewController:alertFind animated:true completion:nil];
  343. }
  344. - (void)alertShowWithString:(NSString *)string {
  345. [RQ_SHARE_FUNCTION showAlertWithTitle:@"温馨提示" message:string alertControllerStyle:UIAlertControllerStyleAlert cancelButtonTitle:@"取消" otherButtonTitles:@[@"确定"] otherButtonStyles:nil showInWindow:NO completion:^(NSUInteger selectedOtherButtonIndex) {
  346. if (selectedOtherButtonIndex == 0) {
  347. switch (order) {
  348. case -1:
  349. {
  350. [self downloadFJJP];
  351. }
  352. break;
  353. case 1://非计划实操计时
  354. {
  355. NSDictionary *dic = @{@"scanType":@"scPeriod",@"dataString":dataString};
  356. if (scanBlock) {
  357. scanBlock(dic);
  358. [self.navigationController popViewControllerAnimated:YES];
  359. }
  360. }
  361. break;
  362. case 2://计划实操计时
  363. {
  364. NSDictionary *dic = @{@"scanType":@"jhPeriod",@"dataString":dataString};
  365. if (scanBlock) {
  366. scanBlock(dic);
  367. [self.navigationController popViewControllerAnimated:YES];
  368. }
  369. }
  370. break;
  371. case 3://结束计时
  372. {
  373. NSDictionary *dic = @{@"scanType":@"allSignOut",@"dataString":dataString};
  374. if (scanBlock) {
  375. scanBlock(dic);
  376. [self.navigationController popViewControllerAnimated:YES];
  377. }
  378. }
  379. break;
  380. case 4://模拟计时开始
  381. {
  382. NSDictionary *dic = @{@"scanType":@"imPeriod",@"dataString":dataString};
  383. if (scanBlock) {
  384. scanBlock(dic);
  385. [self.navigationController popViewControllerAnimated:YES];
  386. }
  387. }
  388. break;
  389. case 5://模拟计时开始/结束
  390. {
  391. NSDictionary *dic = @{@"scanType":@"imitatePeriod",@"dataString":dataString};
  392. if (scanBlock) {
  393. scanBlock(dic);
  394. [self.navigationController popViewControllerAnimated:YES];
  395. }
  396. }
  397. break;
  398. default:
  399. break;
  400. }
  401. }else if (selectedOtherButtonIndex == NSNotFound) {
  402. //取消就重新打开扫描
  403. [session startRunning];
  404. [timer setFireDate:[NSDate distantPast]];
  405. return;
  406. }
  407. }];
  408. }
  409. //登录网页社会公众平台
  410. -(void)downloadFJJP
  411. {
  412. if (!dataString || dataString.length < 1) {
  413. [session startRunning];
  414. [timer setFireDate:[NSDate distantPast]];
  415. return;
  416. }
  417. //发送请求
  418. [LoadingView showHUD];
  419. NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
  420. NSString *account = [ud objectForKey:@"identifyNum"];
  421. NSString *key = [ud objectForKey:@"password"];
  422. NSString *params = [NSString stringWithFormat:@"%@;%@;%@",dataString,account,key];
  423. //NSLog(@"获取的二维码---->%@----\nparams---->%@\n---->%@",object.stringValue,params,[DES3Util encrypt:params]);
  424. NSString *URL = [NSString stringWithFormat:@"http://www.jppt.com.cn/gzpt/index/phoneLogin?params=%@",[DES3Util encrypt:params]];
  425. NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  426. [request setURL:[NSURL URLWithString:URL]];
  427. [request setHTTPMethod:@"GET"];
  428. NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  429. // 返回数据转为字符串
  430. RemoveHUD();
  431. NSString *dataStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  432. if ([dataStr isEqualToString:@"true"]) {
  433. ShowMsg(@"登录成功");
  434. [self.navigationController popViewControllerAnimated:YES];
  435. }else{
  436. ShowMsg(@"登录失败");
  437. [session startRunning];
  438. [timer setFireDate:[NSDate distantPast]];
  439. }
  440. }];
  441. [task resume];
  442. }
  443. -(void)scanBlock:(MyBlockType)block
  444. {
  445. scanBlock = block;
  446. }
  447. - (CGRect)rectOfInterestByScanViewRect:(CGRect)rect {
  448. CGFloat width = CGRectGetWidth(self.view.frame);
  449. CGFloat height = CGRectGetHeight(self.view.frame);
  450. CGFloat x = (height - CGRectGetHeight(rect)) / 2 / height;
  451. CGFloat y = (width - CGRectGetWidth(rect)) / 2 / width;
  452. CGFloat w = CGRectGetHeight(rect) / height;
  453. CGFloat h = CGRectGetWidth(rect) / width;
  454. return CGRectMake(x, y, w, h);
  455. }
  456. #pragma mark - 添加模糊效果
  457. - (void)setOverView {
  458. CGFloat width = CGRectGetWidth(self.view.frame);
  459. CGFloat height = CGRectGetHeight(self.view.frame);
  460. CGFloat x = CGRectGetMinX(scanBackground.frame);
  461. CGFloat y = CGRectGetMinY(scanBackground.frame);
  462. CGFloat w = CGRectGetWidth(scanBackground.frame);
  463. CGFloat h = CGRectGetHeight(scanBackground.frame);
  464. [self creatView:CGRectMake(0, 0, width, y)];
  465. [self creatView:CGRectMake(0, y, x, h)];
  466. [self creatView:CGRectMake(0, y + h, width, height - y - h)];
  467. [self creatView:CGRectMake(x + w, y, width - x - w, h)];
  468. }
  469. - (void)creatView:(CGRect)rect {
  470. CGFloat alpha = 0.5;
  471. UIColor *backColor = [UIColor grayColor];
  472. UIView *view = [[UIView alloc] initWithFrame:rect];
  473. view.backgroundColor = backColor;
  474. view.alpha = alpha;
  475. [self.view addSubview:view];
  476. }
  477. - (void)didReceiveMemoryWarning {
  478. [super didReceiveMemoryWarning];
  479. }
  480. @end