首页
网站首页
公司简介
资讯中心
推荐内容
返回顶部
跑马灯动画实现方式,二维码扫描和应用跳转
发布时间:2020-04-07 02:52
浏览次数:
  • 二话不说就上图,大家看看效果先

1.先说说iOS 应用程序5个状态:

前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢?

-startAnimation{

图片 1上海市图片 2云南省

停止运行-应用程序已经终止,或者还未启动。

在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如ZXing或者ZBar。使用时集成麻烦,出错也不方便调试。在iOS7之后,苹果自身提供了二维码的扫描功能,从效率上来说,原生的二维码远高于这些第三方框架。本文讲解如何使用原生框架实现二维码扫描功能,并且进行扫描后的项目跳转。ps:本期的源代码会在文章结尾给出链接

//取消所有的动画

本篇文章主要涉及讲解表视图和集合视图和网络请求解析数据
  • 以下的类的创建:

图片 3

这里我给一个URL定位符:

http://apis.map.qq.com/ws/district/v1/list?key=K3VBZ-M6WWV-PPSPY-UVGGC-DRM2Z-PGBMV

这里面是全国34个省直辖市, 市, 自治区, 市区,街道的详细介绍, 今天就讲一下网络请求的数据进行数据解析

@interface ViewController ()<UICollectionViewDelegate, UICollectionViewDataSource, UITableViewDelegate, UITableViewDataSource>@property(nonatomic, retain)NSMutableArray *dataSourceProvinceArray;/**省的集合数组*/@property(nonatomic, retain)UICollectionView *collectionView;/**市的表视图*/@property(nonatomic, retain)UITableView *cityTableView;/**区的表视图*/@property(nonatomic, retain)UITableView *zoneTableView;/**市的集合数组*/@property(nonatomic, retain)NSMutableArray *dataSourceCityArray;/**区的集合数组*/@property(nonatomic, retain)NSMutableArray *dataSourceZoneArray;/***/@property(nonatomic, assign)NSInteger currentProvinceIndex;@end@implementation ViewController
  • 咱们先把属性都准备好, 再把表视图和集合视图的协议签好
- getData{ //请求数据并解析 NSString *strURL = @"http://apis.map.qq.com/ws/district/v1/list?key=K3VBZ-M6WWV-PPSPY-UVGGC-DRM2Z-PGBMV"; NSURL *URL = [NSURL URLWithString:strURL]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; //数据源数组: self.dataSourceProvinceArray = [NSMutableArray array]; NSArray *arr = [dic valueForKey:@"result"]; for (NSDictionary *dic in arr[0]) { ProvinceModel *model = [[ProvinceModel alloc] init]; [model setValuesForKeysWithDictionary:dic]; NSLog(@"%@ * %@", model.fullname, model.id); [self.dataSourceProvinceArray addObject:model]; [model release]; } //collectionView的数据刷新}
  • getData这个方法里是网络请求数据的解析省份数据信息
- getcityDataById:(NSString *)proID{ NSString *urlString = [NSString stringWithFormat:@"http://apis.map.qq.com/ws/district/v1/getchildren?&id=%@&key=K3VBZ-M6WWV-PPSPY-UVGGC-DRM2Z-PGBMV", proID]; NSURL *URL = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSArray *allArray = [dic objectForKey:@"result"]; NSArray *array = [allArray objectAtIndex:0]; //遍历当前数组给madel赋值 self.dataSourceCityArray = [NSMutableArray array]; for (NSDictionary *diction in array) { CityModel *model = [[CityModel alloc] init]; [model setValuesForKeysWithDictionary:diction]; [self.dataSourceCityArray addObject:model]; [model release]; } //请求市后 刷新tableView [self.cityTableView reloadData];}
  • getcityDataById:这个方法里是网络请求数据的解析市数据信息
- getZoneDatabyId:(NSString *)cityID{ NSString *urlString = [NSString stringWithFormat:@"http://apis.map.qq.com/ws/district/v1/getchildren?&id=%@&key=K3VBZ-M6WWV-PPSPY-UVGGC-DRM2Z-PGBMV", cityID]; NSURL *URL = [NSURL URLWithString:urlString]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; NSArray *allArray = [dic objectForKey:@"result"]; NSArray *array = [allArray objectAtIndex:0]; //遍历当前数组给madel赋值 self.dataSourceZoneArray = [NSMutableArray array]; for (NSDictionary *diction in array) { ZoneModel *model = [[ZoneModel alloc] init]; [model setValuesForKeysWithDictionary:diction]; [self.dataSourceZoneArray addObject:model]; [model release]; } //请求区后 刷新tableView [self.zoneTableView reloadData];}
  • getZoneDatabyId:这个方法里是网络请求数据的解析区/街道数据信息
- viewDidLoad { [super viewDidLoad]; //设置省坐标为-1 self.currentProvinceIndex = -1; //解析数据: [self getData]; //初始化瀑布流flowLayout: UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; flowLayout.itemSize = CGSizeMake; flowLayout.minimumInteritemSpacing = 10; flowLayout.minimumLineSpacing = 10; flowLayout.sectionInset = UIEdgeInsetsMake(5, 5, 5, 5); flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; //初始化collectionView self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 20, self.view.frame.size.width, 300) collectionViewLayout:flowLayout]; self.collectionView.delegate = self; self.collectionView.dataSource = self; self.collectionView.backgroundColor = [UIColor whiteColor]; [self.view addSubview:_collectionView]; [_collectionView release]; //注册collectionView的cell [self.collectionView registerClass:[ProvinceCell class] forCellWithReuseIdentifier:@"proCell"]; //初始化市视图 self.cityTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, _collectionView.frame.origin.y + _collectionView.frame.size.height, self.view.frame.size.width / 2.0, self.view.frame.size.height - 20 - _collectionView.frame.size.height) style:UITableViewStylePlain]; self.cityTableView.delegate = self; self.cityTableView.dataSource = self; [self.view addSubview:_cityTableView]; [_cityTableView release]; //注册市tableView的cell [self.cityTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cityCell"]; //初始化区视图 self.zoneTableView = [[UITableView alloc] initWithFrame:CGRectMake(self.view.frame.size.width / 2.0, _collectionView.frame.origin.y + _collectionView.frame.size.height, self.view.frame.size.width / 2.0, self.view.frame.size.height - 20 - _collectionView.frame.size.height) style:UITableViewStylePlain]; self.zoneTableView.delegate = self; self.zoneTableView.dataSource = self; [self.view addSubview:_zoneTableView]; [_zoneTableView release]; //注册区tableView的cell [self.zoneTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"zoneCell"];}
  • 下面是表视图和集合视图的一些代理方法:
//--------------------------省collecctionView的代理方法--------------------------//- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return self.dataSourceProvinceArray.count;}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ ProvinceCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"proCell" forIndexPath:indexPath]; //设置cell显示内容 ProvinceModel *model = [self.dataSourceProvinceArray objectAtIndex:indexPath.row]; cell.proNameLabel.text = model.fullname; return cell;}//item的点击方法- collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ //判断当前省是否正在选中 if (self.currentProvinceIndex != indexPath.row) { //获取当前省的model: ProvinceModel *model = [self.dataSourceProvinceArray objectAtIndex:indexPath.item]; [self getcityDataById:model.id]; //清空区的数组并更新 [self.dataSourceZoneArray removeAllObjects]; [self.zoneTableView reloadData]; self.currentProvinceIndex = indexPath.row; }}//--------------------------城市tableView的代理方法--------------------------//- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ if (tableView == _cityTableView) { return self.dataSourceCityArray.count; } else { return self.dataSourceZoneArray.count; }}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == _cityTableView) { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cityCell"]; CityModel *model = [self.dataSourceCityArray objectAtIndex:indexPath.row]; cell.textLabel.text = model.fullname; return cell; } else { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"zoneCell"]; ZoneModel *model = [self.dataSourceZoneArray objectAtIndex:indexPath.row]; cell.textLabel.text = model.fullname; return cell; }}- tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ if (tableView == _cityTableView) { CityModel *model = [self.dataSourceCityArray objectAtIndex:indexPath.row]; [self getZoneDatabyId:model.id]; }}

这里面只有一个属性

@property(nonatomic, retain)UILabel *proNameLabel;

- (instancetype)initWithFrame:frame{ self = [super initWithFrame:frame]; if  { self.proNameLabel = [[UILabel alloc] init]; self.proNameLabel.textAlignment = NSTextAlignmentCenter; self.proNameLabel.layer.borderWidth = 0.5; self.proNameLabel.layer.cornerRadius = 5; self.proNameLabel.font = [UIFont systemFontOfSize:12]; [self.contentView addSubview:_proNameLabel]; [_proNameLabel release]; } return self;}//设置空间坐标frame- layoutSubviews{ [super layoutSubviews]; self.proNameLabel.frame = self.bounds;}

不活动-应用程序处于前台但不再接收事件(例如,用户在app处于活动时锁住了设备)。

二维码扫描需要获取摄像头并读取照片信息,因此我们需要导入系统的AVFoundation框架,创建视频会话。我们需要用到一下几个类:

//[self.aUILabel.layer removeAllAnimations];

CityModel.h

@property(nonatomic, copy)NSString *fullname;@property(nonatomic, copy)NSString *name;@property(nonatomic, copy)NSString *id;

活动-app处于“使用中”的状态。

  • AVCaptureSession 会话对象。此类作为硬件设备输入输出信息的桥梁,承担实时获取设备数据的责任
  • AVCaptureDeviceInput 设备输入类。这个类用来表示输入数据的硬件设备,配置抽象设备的port
  • AVCaptureMetadataOutput 输出类。这个支持二维码、条形码等图像数据的识别
  • AVCaptureVideoPreviewLayer 图层类。用来快速呈现摄像头获取的原始数据二维码扫描功能的实现步骤是创建好会话对象,用来获取从硬件设备输入的数据,并实时显示在界面上。在扫描到相应图像数据的时候,通过AVCaptureVideoPreviewLayer类型进行返回

//计算实际text大小

CityModel.m 和 ZoneModel.m

Model我们都只写一个容错方法就可以

- setValue:value forUndefinedKey:(NSString *)key{}

后台-app不再屏幕上显示,但它仍然执行代码。

在使用第三方登陆、分享sdk的时候,我们的项目会在本机安装有目标平台的应用的情况下进行应用跳转,并且传递信息过去。这在沙盒机制下的iOS应用而言,理应是不符合规则的。但是,iOS SDK给我们提供了一个叫做url scheme的机制来实现这个功能。

CGSizetextSize = [self.aUILabel.textsizeWithAttributes:@{NSFontAttributeName:self.aUILabel.font}];

ZoneModel.h

@property(nonatomic, copy)NSString *fullname;@property(nonatomic, copy)NSString *name;@property(nonatomic, copy)NSString *id;

挂起-app仍然驻留内存但不再执行代码。

url scheme让我们可以像使用Safari打开网页的方式跳转到其他应用中,并使用类似网络请求的GET请求的参数拼凑方式来在不同应用之间传递数据。

//保存label的frame值

大功告成了, 小伙伴们是不是感觉真神奇! 中国那么大, 我想去看看! 要想去看看, 给个好评先!

按下Home键时,app从活动状态转入后台,绝大部分app通常在几秒内就从后台变成了挂起。

使用url scheme的第一步是在项目的info.plist文件中添加新row,命名为URL types

CGRectlframe =self.aUILabel.frame;

在内存吃紧的时候,iphone会首先关闭那些挂起的app。

图片 41.png

//用计算出来的text的width更改frame的原始width

从 iOS 4 开始,应用就可以在退到后台后,继续运行一小段时间;

展开新增的字典,我们修改其中的URL Identifier以及新增加一个字段URL Schemes。Identifier用来跳转后,让跳转应用识别从哪里跳转过来的,我们可以设置为bundleID反转,来确保其特殊性。URL Schemes是一个数组,我们将在这个数组里面自定义自己的url schemes,这里我们填写应用名。最终效果如下:

lframe.size.width= textSize.width;

2.还可以把自己声明为需要在后台运行,就能不限时地运行了。

图片 59A8E2746-D1D9-4BC2-81FE-23E13C5EF202.png

//从屏幕最右边向左边移动

不过限制为播放音乐、使用 GPS 、voip、。 值得一提的是,有的应用为了达到后台不限时运行的目的,在后台播放无声的音乐(审核不一定会被发现)。

接着,我们就可以在其他应用中通过openURL:方法打开我们的app。

lframe.origin.x=self.view.bounds.size.width;

iOS 5 开始又多了一种类型:下载报刊杂志。

二维码扫描的步骤:1、创建设备会话对象,用来设置设备数据输入2、获取摄像头,并且将摄像头对象加入当前会话中3、实时获取摄像头原始数据显示在屏幕上4、扫描到二维码/条形码数据,通过协议方法回调

//用新值更改label的原frame值

然后 iOS 7 则可以下载各种玩意和定时抓取。

  • 会话对象AVCaptureSession的创建_session = [AVCaptureSession new];[_session setSessionPreset: AVCaptureSessionPresetHigh]; //高质量采集[self setupIODevice];

  • setupIODevice方法中懒加载方式创建输入对象和输出对象,注意必须在输出数据对象加入到当前会话后才能设置识别的数据格式。这里设置为扫描二维码以及条形码[_session addInput: self.input];[_session addOutput: self.output];_output.metadataObjectTypes = @[AVMetadataObjectTypeQRCode, AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code];

  • 创建AVCaptureMetadataOutput设置好扫描成功回调代理以及回调线程_output = [AVCaptureMetadataOutput new];[_output setMetadataObjectsDelegate: self queue: dispatch_get_main_queue()];

  • 创建AVCaptureDeviceInput输入设备为手机摄像头AVCaptureDevice * device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];_input = [AVCaptureDeviceInput deviceInputWithDevice: device error: nil];

  • 创建AVCaptureVideoPreviewLayer对象来实时获取摄像头图像,我们需要调用[self.view addSubview: self.scanView]把摄像头获取的图像实时展示在屏幕上_scanView = [AVCaptureVideoPreviewLayer layerWithSession: self.session];_scanView.videoGravity = AVLayerVideoGravityResizeAspectFill;_scanView.frame = self.bounds;

  • 实现captureOutput: didOutputMetadataObjects: fromConnection:来获取扫描得到的数据。回调参数metadataObjects中存放了扫描结果,我们需要先判断这个数组的数据个数不为0再执行下面的代码:[self stop];AVMetadataMachineReadableCodeObject * metadataObject = metadataObjects[0];if ([self.delegate respondsToSelector: @selector(scanView:codeInfo:)]) {[self.delegate scanView: self codeInfo: metadataObject.stringValue];[self removeFromSuperview];} else {[[NSNotificationCenter defaultCenter] postNotificationName: LXDSuccessScanQRCodeNotification object: self userInfo: @{ LXDScanQRCodeMessageKey: metadataObject.stringValue }];

self.aUILabel.frame= lframe;

iOS 7 需要注意的区别:iOS 7 以前,应用进入后台继续运行时,如果用户锁屏了,那么 iOS 会等待应用运行完,才进入睡眠状态。而在 iOS 7 上,系统会很快进入睡眠状态,那些后台应用也就暂停了。如果收到事件被唤醒(例如定时事件、推送、位置更新等),后台应用才能继续运行一会。因为处理过程变成了断断续续的,因此下载时也要使用 NSURLSession 来处理(即下文中的 Background Transfer Service)。

首先要说明的是,二维码并非一定要存储应用的url scheme。例如公众号的二维码,虽然不知道是怎样的数据存储,但肯定不是应用跳转。可以给自己的应用指定一个二维码数据规则,例如支付宝付款扫描是读取商品的ID、价格等信息,然后进行页面跳转付款。这里我们使用上面设置的url scheme,我们通过制作二维码方法来定制一个存储应用跳转信息的二维码,通过下面的代理创建一个存储url scheme(使用url scheme的时候要注意在后面加上://后才能使用openURL进行跳转)的二维码,这一步应该放到模拟器上面生成

//计算动画x移动的最大偏移:屏幕width+text的width

  1. 在我看来,苹果限制 app在后台运行,是为了更有效的利用硬件使用当前的app,不然,过多的app驻留后台,对手机资源占用是一大问题。
  • createBarcode:sender{UIImage * image = [UIImage imageOfQRFromURL: @"LXDDrawLosts://" codeSize: 160.f red: 123 green: 189 blue: 229 insertImage: nil];CGSize size = image.size;UIImageView * imageView = [[UIImageView alloc] initWithFrame: {(CGPointZero), ];imageView.center = self.view.center;imageView.image = image;[self.view addSubview: imageView];}

floatoffset = textSize.width+self.view.bounds.size.width;

友情链接: 网站地图
Copyright © 2015-2019 http://www.nflfreepicks.net. 新葡萄京娱乐场网址有限公司 版权所有