内容简介:CoreLocation框架中使用CLLocationManager对象来做用户定位 创建(初始化)locations参数里面装着CLLocation对象判断定位功能是否可用(为了严谨起见,最好在使用定位功能前进行判断)
-
CoreLocation框架
- CoreLocation
- CLLocation
- ios地图开发的隐私保护(如何添加授权)
- CLGeocoder
- CLPlacemark
-
MapKit框架
- MKMapView
- MKCoordinateRegion
- MKMapView的代理
- MKUserLocation
- 大头针
- annotation
- 自定义大头针
- MKAnnotationView
- MKPinAnnotationView
- MKMapItem调用系统APP进行导航
- MKMapCamera地图街景
- MKMapSnapshotter地图截图
二、大框架
CoreLocation:用于地理定位,地理编码区域监听等(着重功能实现) MapKit:用于地图展示,例如大头针,路线,覆盖层展示等(着重界面展示) 复制代码
CoreLocation框架的使用
CLLocationManager
CoreLocation框架中使用CLLocationManager对象来做用户定位 创建(初始化)
CLLocationManager *lM = [[CLLocationManager alloc] init]; 复制代码
常用属性
-
每隔多少米定位一次
@property(assign, nonatomic) CLLocationDistance distanceFilter; 复制代码
-
定位精确度(越精确就越耗电)
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy; 复制代码
-
朝向改变时,每隔多少度调用一次
@property(assign, nonatomic) CLLocationDegrees headingFilter 复制代码
-
每隔多米定位一次
_lM.distanceFilter = 100; /** kCLLocationAccuracyBestForNavigation // 最适合导航 kCLLocationAccuracyBest; // 最好的 kCLLocationAccuracyNearestTenMeters; // 10m kCLLocationAccuracyHundredMeters; // 100m kCLLocationAccuracyKilometer; // 1000m kCLLocationAccuracyThreeKilometers; // 3000m */ // 精确度越高, 越耗电, 定位时间越长 _lM.desiredAccuracy = kCLLocationAccuracyBest; 复制代码
常用方法
- 开始更新用户位置
- (void)startUpdatingLocation; 复制代码
- 当调用了startUpdatingLocation方法后,就开始不断地请求、刷新用户的位置,一旦请求到用户位置就会调用代理的下面方法
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations; 复制代码
locations参数里面装着CLLocation对象
- 停止更新用户位置
- (void) stopUpdatingLocation; 复制代码
判断定位功能是否可用(为了严谨起见,最好在使用定位功能前进行判断)
+ (BOOL)locationServicesEnabled; 复制代码
监听设备朝向
-(void)startUpdatingHeading(如试例代码中的指南针的实现) 复制代码
区域监听(监听进出某个区域)
-(void)requestStateForRegion:region; 复制代码
//使用位置管理者,开始更新用户位置 // 默认只能在前台获取用户位置, // 勾选后台模式 location updates [self.lM startUpdatingLocation]; 复制代码
//监听设备朝向 [self.lM startUpdatingHeading]; 复制代码
- 区域监听(监听进出某个区域) [self.lM requestStateForRegion:region]; 复制代码
代理方法
- 更新位置后调用
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations; 复制代码
- 授权状态改变时调用
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status 复制代码
- 获取手机朝向时调用
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading 复制代码
-
区域监听的代理方法
-
进入区域时调用:
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region 复制代码
-
离开区域时调用:
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region 复制代码
-
监听是否在某个区域的状态:
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state 复制代码
-
进入区域时调用:
/** * 更新到位置之后调用 * * @param manager 位置管理者 * @param locations 位置数组 */ -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"定位到了"); // 拿到位置,做一些业务逻辑操作 // 停止更新 // [manager stopUpdatingLocation]; } 复制代码
/** * 授权状态发生改变时调用 * * @param manager 位置管理者 * @param status 状态 */ -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { switch (status) { // 用户还未决定 case kCLAuthorizationStatusNotDetermined: { NSLog(@"用户还未决定"); break; } // 问受限 case kCLAuthorizationStatusRestricted: { NSLog(@"访问受限"); break; } // 定位关闭时和对此APP授权为never时调用 case kCLAuthorizationStatusDenied: { // 定位是否可用(是否支持定位或者定位是否开启) if([CLLocationManager locationServicesEnabled]) { NSLog(@"定位开启,但被拒"); }else { NSLog(@"定位关闭,不可用"); } // NSLog(@"被拒"); break; } // 获取前后台定位授权 case kCLAuthorizationStatusAuthorizedAlways: // case kCLAuthorizationStatusAuthorized: // 失效,不建议使用 { NSLog(@"获取前后台定位授权"); break; } // 获得前台定位授权 case kCLAuthorizationStatusAuthorizedWhenInUse: { NSLog(@"获得前台定位授权"); break; } default: break; } } 复制代码
/** * 简易指南针的实现 * 手机朝向改变时调用 * * @param manager 位置管理者 * @param newHeading 朝向对象 */ -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { /** * CLHeading * magneticHeading : 磁北角度 * trueHeading : 真北角度 */ NSLog(@"%f", newHeading.magneticHeading); CGFloat angle = newHeading.magneticHeading; // 把角度转弧度 CGFloat angleR = angle / 180.0 * M_PI; // 旋转图片(指南针图片) [UIView animateWithDuration:0.25 animations:^{ self.compassView.transform = CGAffineTransformMakeRotation(-angleR); }]; } 复制代码
//区域监听的代理方法 // 进入区域 -(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region { NSLog(@"进入区域--%@", region.identifier); } // 离开区域 -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region { NSLog(@"离开区域--%@", region.identifier); } //监听是否在某个区域的状态 -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region { //state的值 //CLRegionStateUnknown, //CLRegionStateInside, //CLRegionStateOutside NSLog(@"%zd", state); } 复制代码
CLLocation
-
CLLocation用来表示某个位置的地理信息,比如经纬度,海拔等等
-
常用属性
- 经纬度
@property(readonly, nonatomic) CLLocationCoordinate2D coordinate; 复制代码
- 海拔
@property(readonly, nonatomic) CLLocationDistance altitude; 复制代码
- 路线,航向(取值范围是0.0° ~ 359.9°,0.0°代表真北方向)
@property(readonly, nonatomic) CLLocationDirection course; 复制代码
- 移动速度(单位是m/s)
@property(readonly, nonatomic) CLLocationSpeed speed; 复制代码
-
常用方法
- 计算两个位置之间的距离:
- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location 复制代码
使用试例:根据移动方向打印出移动的方向和距离
/** * CLLocationManager对象的代理方法,当用户位置改变的时候调用 * 更新到位置之后调用 * * @param manager 位置管理者 * @param locations 位置数组 * is kind of */ -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { // NSLog(@"定位到了"); /** * CLLocation 详解 * coordinate : 经纬度 * altitude : 海拔 * course : 航向 * speed ; 速度 */ CLLocation *location = [locations lastObject]; // NSLog(@"%@", location); /** * 场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离, 例如:”北偏东 30度 方向,移动了8米” */ // 1. 获取方向偏向 NSString *angleStr = nil; switch ((int)location.course / 90) { case 0: angleStr = @"北偏东"; break; case 1: angleStr = @"东偏南"; break; case 2: angleStr = @"南偏西"; break; case 3: angleStr = @"西偏北"; break; default: angleStr = @"跑沟里去了!!"; break; } // 2. 偏向角度 NSInteger angle = 0; angle = (int)location.course % 90; // 代表正方向 if (angle == 0) { NSRange range = NSMakeRange(0, 1); angleStr = [NSString stringWithFormat:@"正%@", [angleStr substringWithRange:range]]; } // 3.移动多少米 double distance = 0; if(_oldL) { distance = [location distanceFromLocation:_oldL]; } _oldL = location; // 4. 拼串 打印 // 例如:”北偏东 30度 方向,移动了8米” NSString *noticeStr = [NSString stringWithFormat:@"%@%zd方向, 移动了%f米", angleStr, angle, distance]; NSLog(@"%@", noticeStr); } 复制代码
ios地图开发用户隐私保护(授权)
ios6+
-
当使用定位时,系统会自动弹出对话框让用户授权。
- 一旦用户选择了不允许,意味着应用程序以后都无法使用定位。
- 开发者可以在Info.plist中设置NSLocationUsageDescription说明定位的目的(Privacy - Location Usage Description)
ios8.0+
-
从ios8.0开始,苹果进一步加强了对用户隐私的保护。
-
当app想访问用户的隐私时,系统不再自动弹出一个对话框让用户授权.
解决方案
-
(1)调用ios8.0的api。主动请求用户授权
- -(void)requestAlwaysAuthorization // 请求允许在前后台都能获取用户位置的授权
- -(void)requestWhenInUseAuthorization // 请求允许在前台获取用户位置的授权(注意:当设置为前台授权时,通过设置后台模式:location updates后 也可以后台获取定位信息,但是屏幕上方会出现蓝条)
-
(2)务必在info.plist文件中配置对应的键值, 否则以上请求授权的方法不生效
- NSLocationAlwaysUsageDescription : 允许在前后台获取GPS的描述
- NSLocationWhenInUseDescription : 允许在前台获取GPS的描述
ios9.0
-
ios9.0如果当前处于前台授权状态,默认是不可以后台获取用户位置。但可以设置以下属性为YES,就可以继续在后台获取位置,但是在屏幕上方会出现蓝条
- @property(assign, nonatomic) BOOL allowsBackgroundLocationUpdates
- 使用注意:必须设置对应的后台模式:location updates
-
ios9.0可以单次请求用户位置
- -(void)requestLocation
- -(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations // 成功调用
- -(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // 失败调用
CLGeocoder
-
使用CLGeocoder可以完成“地理编码”和“反地理编码”
- 地理编码:根据给定的地名,获得具体的位置信息(比如经纬度、地址的全称等)
- 反地理编码:根据给定的经纬度,获得具体的位置信息
-
对应方法
- 地理编码方法
-(void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler; 复制代码
- 反地理编码方法
-(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler; 复制代码
-
CLGeocodeCompletionHandler:反地理编码完成时,就会调用CLGeocodeCompletionHandler
-
typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);
- error :当编码出错时(比如编码不出具体的信息)有值
- placemarks :里面装着CLPlacemark对象
-
地理编码的实现
// 地理编码 - (IBAction)geoCoder { //当传入的值为0时直接返回 if ([self.addressDetailTV.text length] == 0) { return; } // 地理编码方案一:直接根据地址进行地理编码(返回结果可能有多个,因为一个地点有重名) [self.geoC geocodeAddressString:self.addressDetailTV.text completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) { // 包含区,街道等信息的地标对象 CLPlacemark *placemark = [placemarks firstObject]; // 城市名称 // NSString *city = placemark.locality; // 街道名称 // NSString *street = placemark.thoroughfare; // 全称 NSString *name = placemark.name; self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name]; self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude]; self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude]; }]; // 地理编码方案二:根据地址和区域两个条件进行地理编码(更加精确) // [self.geoC geocodeAddressString:self.addressDetailTV.text inRegion:nil completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) { // // 包含区,街道等信息的地标对象 // CLPlacemark *placemark = [placemarks firstObject]; // self.addressDetailTV.text = placemark.description; // self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude]; // self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude]; // }]; // 地理编码方案三: // NSDictionary *addressDic = @{ // (__bridge NSString *)kABPersonAddressCityKey : @"北京", // (__bridge NSString *)kABPersonAddressStreetKey : @"棠下街" // }; // [self.geoC geocodeAddressDictionary:addressDic completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) { // CLPlacemark *placemark = [placemarks firstObject]; // self.addressDetailTV.text = placemark.description; // self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude]; // self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude]; // }]; } 复制代码
反地理编码的实现
// 反地理编码 - (IBAction)decode { // 过滤空数据 if ([self.latitudeTF.text length] == 0 || [self.longtitudeTF.text length] == 0) { return; } // 创建CLLocation对象 CLLocation *location = [[CLLocation alloc] initWithLatitude:[self.latitudeTF.text doubleValue] longitude:[self.longtitudeTF.text doubleValue]]; // 根据CLLocation对象进行反地理编码 [self.geoC reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) { // 包含区,街道等信息的地标对象 CLPlacemark *placemark = [placemarks firstObject]; // 城市名称 // NSString *city = placemark.locality; // 街道名称 // NSString *street = placemark.thoroughfare; // 全称 NSString *name = placemark.name; self.addressDetailTV.text = [NSString stringWithFormat:@"%@", name]; }]; } 复制代码
CLPlacemark
-
CLPlacemark的字面意思是地标,封装详细的地址位置信息 常用属性
- 地理位置
@property (nonatomic, readonly) CLLocation *location; 复制代码
- 区域
@property (nonatomic, readonly) CLRegion *region; 复制代码
- 详细的地址信息
@property (nonatomic, readonly) NSDictionary *addressDictionary; 复制代码
- 地址名称
@property (nonatomic, readonly) NSString *name; 复制代码
- 城市
@property (nonatomic, readonly) NSString *locality; 复制代码
MapKit框架的使用
MapKit通过MKMapView来显示地图
-
常用属性
-
地图配型:mapType
- MKMapTypeStandard :普通地图(左图)
- MKMapTypeSatellite :卫星云图 (中图)
- MKMapTypeHybrid :混合模式(普通地图覆盖于卫星云图之上 )
- MKMapTypeSatelliteFlyover: 3D立体卫星 (iOS9.0)
- MKMapTypeHybridFlyover: 3D立体混合 (iOS9.0)
-
-
操作项
- 是否可缩放 zoomEnabled
- 是否可滚动 scrollEnabled
- 是否可旋转 rotateEnabled
-
显示项
- 是否显示指南针 showsCompass (iOS9.0)
- 是否显示比例尺 showsScale (iOS9.0)
- 是否显示交通 showsTraffic (iOS9.0)
- 是否显示建筑 showsBuildings
-
跟踪显示用户的位置(ios8-地图不会自动滚到用户所在的位置,ios8+地图会自动放大到合适比例,并显示出用户位置)
- MKUserTrackingModeNone :不跟踪用户的位置
- MKUserTrackingModeFollow :跟踪并在地图上显示用户的当前位置
- MKUserTrackingModeFollowWithHeading :跟踪并在地图上显示用户的当前位置,地图会跟随用户的前进方向进行旋转
-
设置地图显示的区域和位置
-
设置地图的中心点位置
- @property (nonatomic) CLLocationCoordinate2D centerCoordinate;
- -(void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
-
设置地图的显示区域
- @property (nonatomic) MKCoordinateRegion region;
- -(void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;
-
MKCoordinateRegion
- MKCoordinateRegion是一个用来表示区域的结构体
typedef struct { CLLocationCoordinate2D center; // 区域的中心点位置 MKCoordinateSpan span; // 区域的跨度 } MKCoordinateRegion; 复制代码
- MKCoordinateSpan
typedef struct { CLLocationDegrees latitudeDelta; // 纬度跨度 CLLocationDegrees longitudeDelta; // 经度跨度 } MKCoordinateSpan; 复制代码
MKMapView的代理
-
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;
- 一个位置更改默认只会调用一次,不断监测用户的当前位置
- 每次调用,都会把用户的最新位置(userLocation参数)传进来
-
-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;
- 地图的显示区域即将发生改变的时候调用
-
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;
- 地图的显示区域已经发生改变的时候调用
MKUserLocation
-
@property (nonatomic, copy) NSString *title;
- 显示在大头针上的标题
-
@property (nonatomic, copy) NSString *subtitle;
- 显示在大头针上的子标题
-
@property (readonly, nonatomic) CLLocation *location;
- 地理位置信息(大头针钉在什么地方?)
大头针
-
添加大头针
-
添加一个大头针
- -(void)addAnnotation:(id )annotation;
-
添加多个大头针
- -(void)addAnnotations:(NSArray *)annotations;
-
添加一个大头针
-
移除大头针
-
移除一个大头针
- -(void)removeAnnotation:(id )annotation;
-
移除多个大头针
- -(void)removeAnnotations:(NSArray *)annotations;
-
移除一个大头针
annotation
- 大头针模型对象
#import <MapKit/MapKit.h> @interface TestAnnotation : NSObject <MKAnnotation> /** 坐标位置 */ @property (nonatomic, assign) CLLocationCoordinate2D coordinate; /** 标题 */ @property (nonatomic, copy) NSString *title; /** 子标题 */ @property (nonatomic, copy) NSString *subtitle; @end 复制代码
自定义大头针
-
设置MKMapView代理
-
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation;
- 根据传进来的(id )annotation参数创建并返回对应的大头针控件
- 注意:如果返回nil,显示出来的大头针就采取系统的默认样式
- 标识用户位置的蓝色发光圆点,它也是一个大头针,当显示这个大头针时,也会调用代理方法
- 因此,需要在代理方法中分清楚(id )annotation参数代表自定义的大头针还是蓝色发光圆点
-
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation;
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { // 判断annotation的类型 if (![annotation isKindOfClass:[TestAnnotation class]]) return nil; // 创建MKAnnotationView static NSString *ID = @"tuangou"; MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID]; if (annoView == nil) { annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID]; annoView.canShowCallout = YES; } 复制代码
MKAnnotationView
地图上的大头针控件是MKAnnotationView
-
属性
-
@property (nonatomic, strong) id annotation;
- 大头针模型
-
@property (nonatomic, strong) UIImage *image;
- 显示的图片
-
@property (nonatomic) BOOL canShowCallout;
- 是否显示标注
-
@property (nonatomic) CGPoint calloutOffset;
- 标注的偏移量
-
@property (strong, nonatomic) UIView *rightCalloutAccessoryView;
- 标注右边显示什么控件
-
@property (strong, nonatomic) UIView *leftCalloutAccessoryView;
- 标注左边显示什么控件
-
@property (nonatomic, strong) UIView *detailCalloutAccessoryView
- 标注下面显示什么控件(iOS9.0)
-
@property (nonatomic, strong) id annotation;
MKPinAnnotationView
MKPinAnnotationView是MKAnnotationView的子类
-
MKPinAnnotationView比MKAnnotationView多了2个属性
-
@property (nonatomic) MKPinAnnotationColor pinColor;
- 大头针颜色
-
@property (nonatomic) BOOL animatesDrop;
- 大头针第一次显示时是否从天而降
-
@property (nonatomic) MKPinAnnotationColor pinColor;
MKMapItem调用系统APP进行导航
// 根据两个地标对象进行调用系统导航 - (void)beginNavWithBeginPlacemark:(CLPlacemark *)beginPlacemark andEndPlacemark:(CLPlacemark *)endPlacemark { // 创建起点:根据 CLPlacemark 地标对象创建 MKPlacemark 地标对象 MKPlacemark *itemP1 = [[MKPlacemark alloc] initWithPlacemark:beginPlacemark]; MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:itemP1]; // 创建终点:根据 CLPlacemark 地标对象创建 MKPlacemark 地标对象 MKPlacemark *itemP2 = [[MKPlacemark alloc] initWithPlacemark:endPlacemark]; MKMapItem *item2 = [[MKMapItem alloc] initWithPlacemark:itemP2]; NSDictionary *launchDic = @{ // 设置导航模式参数 MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving, // 设置地图类型 MKLaunchOptionsMapTypeKey : @(MKMapTypeHybridFlyover), // 设置是否显示交通 MKLaunchOptionsShowsTrafficKey : @(YES), }; // 根据 MKMapItem 数组 和 启动参数字典 来调用系统地图进行导航 [MKMapItem openMapsWithItems:@[item1, item2] launchOptions:launchDic]; } 复制代码
MKMapCamera地图街景
// 创建视角中心坐标 CLLocationCoordinate2D center = CLLocationCoordinate2DMake(23.132931, 113.375924); // 创建3D视角 MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:center fromEyeCoordinate:CLLocationCoordinate2DMake(center.latitude + 0.001, center.longitude + 0.001) eyeAltitude:1]; // 设置到地图上显示 self.mapView.camera = camera; 复制代码
MKMapSnapshotter地图截图
// 截图附加选项 MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init]; // 设置截图区域(在地图上的区域,作用在地图) options.region = self.mapView.region; // options.mapRect = self.mapView.visibleMapRect; // 设置截图后的图片大小(作用在输出图像) options.size = self.mapView.frame.size; // 设置截图后的图片比例(默认是屏幕比例, 作用在输出图像) options.scale = [[UIScreen mainScreen] scale]; MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options]; [snapshotter startWithCompletionHandler:^(MKMapSnapshot * _Nullable snapshot, NSError * _Nullable error) { if (error) { NSLog(@"截图错误:%@",error.localizedDescription); }else { // 设置屏幕上图片显示 self.snapshootImageView.image = snapshot.image; // 将图片保存到指定路径(此处是桌面路径,需要根据个人电脑不同进行修改) NSData *data = UIImagePNGRepresentation(snapshot.image); [data writeToFile:@"/Users/wangshunzi/Desktop/snap.png" atomically:YES]; } }]; 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 观点 | 关于区块链应用,我们需要一个更好的框架
- 有了Julia语言,深度学习框架从此不需要计算图
- 公司为什么需要建立一套统一的开发框架?
- 深度学习框架中的「张量」不好用?也许我们需要重新定义Tensor了
- GitHub上星数排行前6的VUE框架,看看有没有你需要的
- Mars-java 2.2.2 发布,不需要容器的 Java Web 开发框架
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
免费:商业的未来
Chris Anderson / 中信出版集团 / 2015-10-1 / 35.40
《免费》,这是一个商业模式不断被颠覆、被改写的时代。一种商业模式既可以统摄未来市场,也可以挤垮当前市场——在我们这个现代经济社会里,这并不是一件不可能的事情。“免费”就是这样的一种商业模式,它代表了互联网时代的商业未来。 “免费”商业模式是一种建立在以电脑字节为基础上的经济学,而非过去建立在物理原子基础上的经济学。在原子经济中,随着时间的推移,我们周围的物品都在逐渐升值。但是在字节经济的网络......一起来看看 《免费:商业的未来》 这本书的介绍吧!
CSS 压缩/解压工具
在线压缩/解压 CSS 代码
Base64 编码/解码
Base64 编码/解码