iOS实现“摇一摇”与“扫一扫”功能示例代码
程序员文章站
2023-12-21 13:45:04
“摇一摇”功能的实现:
iphone对 “摇一摇”有很好的支持,总体说来就两步:
在视图控制器中打开接受“摇一摇”的开关;
- (void)viewdi...
“摇一摇”功能的实现:
iphone对 “摇一摇”有很好的支持,总体说来就两步:
在视图控制器中打开接受“摇一摇”的开关;
- (void)viewdidload { // 设置允许摇一摇功能 [uiapplication sharedapplication].applicationsupportsshaketoedit = yes; // 并让自己成为第一响应者 [self becomefirstresponder]; }
在“摇一摇”触发的制定的方法中实现需要实现的功能(”摇一摇“检测方法)。
// 摇一摇开始摇动 - (void)motionbegan:(uieventsubtype)motion withevent:(uievent *)event { nslog(@"开始摇动"); //添加“摇一摇”动画 [self addanimations]; //音效 audioservicesplaysystemsound (soundid); return; } // “摇一摇”取消摇动 - (void)motioncancelled:(uieventsubtype)motion withevent:(uievent *)event { nslog(@"取消摇动"); return; } // “摇一摇”摇动结束 - (void)motionended:(uieventsubtype)motion withevent:(uievent *)event { if (event.subtype == uieventsubtypemotionshake) { // 判断是否是摇动结束 nslog(@"摇动结束"); } return; }
”摇一摇“的动画效果:
- (void)addanimations { //音效 audioservicesplaysystemsound (soundid); //让上面图片的上下移动 cabasicanimation *translation2 = [cabasicanimation animationwithkeypath:@"position"]; translation2.timingfunction = [camediatimingfunction functionwithname:kcamediatimingfunctioneaseineaseout]; translation2.fromvalue = [nsvalue valuewithcgpoint:cgpointmake(160, 115)]; translation2.tovalue = [nsvalue valuewithcgpoint:cgpointmake(160, 40)]; translation2.duration = 0.4; translation2.repeatcount = 1; translation2.autoreverses = yes; //让下面的图片上下移动 cabasicanimation *translation = [cabasicanimation animationwithkeypath:@"position"]; translation.timingfunction = [camediatimingfunction functionwithname:kcamediatimingfunctioneaseineaseout]; translation.fromvalue = [nsvalue valuewithcgpoint:cgpointmake(160, 345)]; translation.tovalue = [nsvalue valuewithcgpoint:cgpointmake(160, 420)]; translation.duration = 0.4; translation.repeatcount = 1; translation.autoreverses = yes; [imgdown.layer addanimation:translation forkey:@"translation"]; [imgup.layer addanimation:translation2 forkey:@"translation2"]; }
注意:在模拟器中运行时,可以通过「hardware」-「shake gesture」来测试「摇一摇」功能。如下:
“扫一扫”功能的实现:
基于avcapturedevice做的二维码扫描器,基本步骤如下:
初始化相机,生成扫描器
设置参数
- (void)setupcamera { dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{ _device = [avcapturedevice defaultdevicewithmediatype:avmediatypevideo]; _input = [avcapturedeviceinput deviceinputwithdevice:_device error:nil]; _output = [[avcapturemetadataoutput alloc]init]; [_output setmetadataobjectsdelegate:self queue:dispatch_get_main_queue()]; _session = [[avcapturesession alloc]init]; [_session setsessionpreset:avcapturesessionpresethigh]; if ([_session canaddinput:self.input]) { [_session addinput:self.input]; } if ([_session canaddoutput:self.output]) { [_session addoutput:self.output]; } // 条码类型 avmetadataobjecttypeqrcode _output.metadataobjecttypes = [nsarray arraywithobjects:avmetadataobjecttypeean13code, avmetadataobjecttypeean8code, avmetadataobjecttypecode128code, avmetadataobjecttypeqrcode, nil]; dispatch_async(dispatch_get_main_queue(), ^{ //更新界面 _preview =[avcapturevideopreviewlayer layerwithsession:self.session]; _preview.videogravity = avlayervideogravityresizeaspectfill; _preview.frame = cgrectmake(0, 0, cgrectgetwidth(self.centerview.frame), cgrectgetheight(self.centerview.frame)); [self.centerview.layer insertsublayer:self.preview atindex:0]; [_session startrunning]; }); }); }
在viewwillappear和viewwilldisappear里对session做优化(timer是个扫描动画的计时器)
- (void)viewwillappear:(bool)animated { [super viewwillappear:animated]; if (_session && ![_session isrunning]) { [_session startrunning]; } timer = [nstimer scheduledtimerwithtimeinterval:0.02 target:self selector:@selector(scanninganimation) userinfo:nil repeats:yes]; [self setupcamera]; } - (void)viewwilldisappear:(bool)animated { [super viewwilldisappear:animated]; _count = 0; [timer invalidate]; [self stopreading]; }
处理扫描结果
- (void)captureoutput:(avcaptureoutput *)captureoutput didoutputmetadataobjects:(nsarray *)metadataobjects fromconnection:(avcaptureconnection *)connection { nsstring *stringvalue; if ([metadataobjects count] >0){ avmetadatamachinereadablecodeobject * metadataobject = [metadataobjects objectatindex:0]; stringvalue = metadataobject.stringvalue; nslog(@"%@",stringvalue); } [_session stoprunning]; [timer invalidate]; _count ++ ; [self stopreading]; if (stringvalue && _count == 1) { //扫描完成 } }
用二维码扫描器扫描自己的二维码:
nsstring *url = [nsurl urlwithstring:@"html/judgement.html" relativetourl:[zxapiclient sharedclient].baseurl].absolutestring; if ([stringvalue hasprefix:url]) { //如果扫出来的url是自己的域名开头的,那么做如下的处理 }
最后附上自己完整的源码:
// created by ydw on 16/3/15. // copyright © 2016年 izhuo.net. all rights reserved. // import “viewcontroller.h” import <avfoundation/avfoundation.h> @interface viewcontroller () { int number; nstimer *timer; nsinteger _count; bool upordown; avcapturedevice *lightdevice; } @property (nonatomic,strong) uiview *centerview;//扫描的显示视图 /** * 二维码扫描参数 */ @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; @property (nonatomic,retain) uiimageview *imageview;//扫描线 (void)setupcamera; (void)stopreading; @end @implementation viewcontroller - (void)viewwillappear:(bool)animated { [super viewwillappear:animated]; if (_session && ![_session isrunning]) { [_session startrunning]; } timer = [nstimer scheduledtimerwithtimeinterval:0.02 target:self selector:@selector(scanninganimation) userinfo:nil repeats:yes]; [self setupcamera]; } - (void)viewdidload { [super viewdidload]; self.view.backgroundcolor = [uicolor clearcolor]; self.automaticallyadjustsscrollviewinsets = no; _count = 0 ; //初始化闪光灯设备 lightdevice = [avcapturedevice defaultdevicewithmediatype:avmediatypevideo]; //扫描范围 _centerview = [[uiview alloc]initwithframe:cgrectmake(0, 0, cgrectgetwidth(self.view.frame), cgrectgetheight(self.view.frame))]; _centerview.backgroundcolor = [uicolor clearcolor]; [self.view addsubview:_centerview]; //扫描的视图加载 uiview *scanningviewone = [[uiview alloc]initwithframe:cgrectmake(0, 0, self.view.frame.size.width, 120)]; scanningviewone.backgroundcolor= [[uicolor blackcolor] colorwithalphacomponent:0.4]; [self.centerview addsubview:scanningviewone]; uiview *scanningviewtwo = [[uiview alloc]initwithframe:cgrectmake(0, 120, (self.view.frame.size.width-300)/2, 300)]; scanningviewtwo.backgroundcolor= [[uicolor blackcolor] colorwithalphacomponent:0.4]; [self.centerview addsubview:scanningviewtwo]; uiview *scanningviewthree = [[uiview alloc]initwithframe:cgrectmake(cgrectgetwidth(self.view.frame)/2+150, 120, (self.view.frame.size.width-300)/2, 300)]; scanningviewthree.backgroundcolor= [[uicolor blackcolor] colorwithalphacomponent:0.4]; [self.centerview addsubview:scanningviewthree]; uiview *scanningviewfour = [[uiview alloc]initwithframe:cgrectmake(0, 420, self.view.frame.size.width,cgrectgetheight(self.view.frame)- 420)]; scanningviewfour.backgroundcolor= [[uicolor blackcolor] colorwithalphacomponent:0.4]; [self.centerview addsubview:scanningviewfour]; uilabel *labintroudction= [[uilabel alloc] initwithframe:cgrectmake(15, 430, self.view.frame.size.width - 30, 30)]; labintroudction.backgroundcolor = [uicolor clearcolor]; labintroudction.textalignment = nstextalignmentcenter; labintroudction.textcolor = [uicolor whitecolor]; labintroudction.text = @"请将企业邀请码放入扫描框内"; [self.centerview addsubview:labintroudction]; uibutton *openlight = [[uibutton alloc]initwithframe:cgrectmake(cgrectgetwidth(self.view.frame)/2-25, 470, 50, 50)]; [openlight setimage:[uiimage imagenamed:@"灯泡"] forstate:uicontrolstatenormal]; [openlight setimage:[uiimage imagenamed:@"灯泡2"] forstate:uicontrolstateselected]; [openlight addtarget:self action:@selector(openlightway:) forcontrolevents:uicontroleventtouchupinside]; [self.centerview addsubview:openlight]; //扫描线 _imageview = [[uiimageview alloc] initwithframe:cgrectmake(cgrectgetwidth(self.view.frame)/2-110, 130, 220, 5)]; _imageview.image = [uiimage imagenamed:@"scanning@3x"]; [self.centerview addsubview:_imageview]; } - (void)viewwilldisappear:(bool)animated { _count= 0; [timer invalidate]; [self stopreading]; } pragma mark -- 设置参数 - (void)setupcamera { dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{ _device = [avcapturedevice defaultdevicewithmediatype:avmediatypevideo]; _input = [avcapturedeviceinput deviceinputwithdevice:_device error:nil]; _output = [[avcapturemetadataoutput alloc]init]; [_output setmetadataobjectsdelegate:self queue:dispatch_get_main_queue()]; _session = [[avcapturesession alloc]init]; [_session setsessionpreset:avcapturesessionpresethigh]; if ([_session canaddinput:self.input]) { [_session addinput:self.input]; } if ([_session canaddoutput:self.output]) { [_session addoutput:self.output]; } // 条码类型 avmetadataobjecttypeqrcode _output.metadataobjecttypes = [nsarray arraywithobjects:avmetadataobjecttypeean13code, avmetadataobjecttypeean8code, avmetadataobjecttypecode128code, avmetadataobjecttypeqrcode, nil]; dispatch_async(dispatch_get_main_queue(), ^{ //更新界面 _preview =[avcapturevideopreviewlayer layerwithsession:self.session]; _preview.videogravity = avlayervideogravityresizeaspectfill; _preview.frame = cgrectmake(0, 0, cgrectgetwidth(self.centerview.frame), cgrectgetheight(self.centerview.frame)); [self.centerview.layer insertsublayer:self.preview atindex:0]; [_session startrunning]; }); }); } //扫描动画 - (void)scanninganimation { if (upordown == no) { number ++; _imageview.frame = cgrectmake(cgrectgetwidth(self.view.frame)/2-115, 130+2*number, 230, 5); if (2*number == 280) { upordown = yes; } } else { number --; _imageview.frame = cgrectmake(cgrectgetwidth(self.view.frame)/2-115, 130+2*number, 230, 5); if (number == 0) { upordown = no; } } } - (void)stopreading { [_session stoprunning]; _session = nil; [_preview removefromsuperlayer]; [timer invalidate]; timer = nil ; } -(void)openlightway:(uibutton *)sender { if (![lightdevice hastorch]) {//判断是否有闪光灯 uialertcontroller *alert = [uialertcontroller alertcontrollerwithtitle:@"当前设备没有闪光灯,不能提供手电筒功能" message:nil preferredstyle:uialertcontrollerstylealert]; uialertaction *sureaction = [uialertaction actionwithtitle:@"确定" style:uialertactionstylecancel handler:nil]; [alert addaction:sureaction]; [self presentviewcontroller:alert animated:yes completion:nil]; return; } sender.selected = !sender.selected; if (sender.selected == yes) { [lightdevice lockforconfiguration:nil]; [lightdevice settorchmode:avcapturetorchmodeon]; [lightdevice unlockforconfiguration]; } else { [lightdevice lockforconfiguration:nil]; [lightdevice settorchmode: avcapturetorchmodeoff]; [lightdevice unlockforconfiguration]; } } pragma mark -- avcapturemetadataoutputobjectsdelegate - (void)captureoutput:(avcaptureoutput *)captureoutput didoutputmetadataobjects:(nsarray *)metadataobjects fromconnection:(avcaptureconnection *)connection { nsstring *stringvalue; if ([metadataobjects count] >0){ avmetadatamachinereadablecodeobject * metadataobject = [metadataobjects objectatindex:0]; stringvalue = metadataobject.stringvalue; nslog(@"%@",stringvalue); } [_session stoprunning]; [timer invalidate]; _count ++ ; [self stopreading]; if (stringvalue && _count == 1) { //扫描完成 } } - (void)didreceivememorywarning { [super didreceivememorywarning]; // dispose of any resources that can be recreated. } @end
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。