当前位置: 首页 > news >正文

红酒网站程序营销推广的方式

红酒网站程序,营销推广的方式,软件外包公司成都,建设网站目标iOS开发--地图与定位 概览 现在很多社交、电商、团购应用都引入了地图和定位功能#xff0c;似乎地图功能不再是地图应用和导航应用所特有的。的确#xff0c;有了地图和定位功能确实让我们的生活更加丰富多彩#xff0c;极大的改变了我们的生活方式。例如你到了一个陌生的地… iOS开发--地图与定位 概览 现在很多社交、电商、团购应用都引入了地图和定位功能似乎地图功能不再是地图应用和导航应用所特有的。的确有了地图和定位功能确实让我们的生活更加丰富多彩极大的改变了我们的生活方式。例如你到了一个陌生的地方想要查找附近的酒店、超市等就可以打开软件搜索周边;类似的还有很多团购软件可以根据你所在的位置自动为你推荐某些商品。总之目前地图和定位功能已经大量引入到应用开发中。今天就和大家一起看一下iOS如何进行地图和定位开发。 定位 要实现地图、导航功能往往需要先熟悉定位功能在iOS中通过Core Location框架进行定位操作。Core Location自身可以单独使用和地图开发框架MapKit完全是独立的但是往往地图开发要配合定位框架使用。在Core Location中主要包含了定位、地理编码包括反编码功能。 定位功能 定位是一个很常用的功能如一些地图软件打开之后如果用户允许软件定位的话那么打开软件后就会自动锁定到当前位置如果用户手机移动那么当前位置也会跟随着变化。要实现这个功能需要使用Core Loaction中CLLocationManager类首先看一下这个类的一些主要方法和属性 类方法 说明 (BOOL)locationServicesEnabled; 是否启用定位服务通常如果用户没有启用定位服务可以提示用户打开定位服务 (CLAuthorizationStatus)authorizationStatus; 定位服务授权状态返回枚举类型 kCLAuthorizationStatusNotDetermined 用户尚未做出决定是否启用定位服务 kCLAuthorizationStatusRestricted 没有获得用户授权使用定位服务,可能用户没有自己禁止访问授权 kCLAuthorizationStatusDenied 用户已经明确禁止应用使用定位服务或者当前系统定位服务处于关闭状态 kCLAuthorizationStatusAuthorizedAlways 应用获得授权可以一直使用定位服务即使应用不在使用状态 kCLAuthorizationStatusAuthorizedWhenInUse 使用此应用过程中允许访问定位服务 属性 说明 desiredAccuracy 定位精度枚举类型 kCLLocationAccuracyBest最精确定位 CLLocationAccuracy kCLLocationAccuracyNearestTenMeters十米误差范围 kCLLocationAccuracyHundredMeters:百米误差范围 kCLLocationAccuracyKilometer:千米误差范围 kCLLocationAccuracyThreeKilometers:三千米误差范围 distanceFilter 位置信息更新最小距离只有移动大于这个距离才更新位置信息默认为kCLDistanceFilterNone不进行距离限制 对象方法 说明 startUpdatingLocation 开始定位追踪开始定位后将按照用户设置的更新频率执行-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;方法反馈定位信息 stopUpdatingLocation 停止定位追踪 startUpdatingHeading 开始导航方向追踪 stopUpdatingHeading 停止导航方向追踪 startMonitoringForRegion: 开始对某个区域进行定位追踪开始对某个区域进行定位后。如果用户进入或者走出某个区域会调用- (void)locationManager:(CLLocationManager *)manager     didEnterRegion:(CLRegion *)region和- (void)locationManager:(CLLocationManager *)manager     didExitRegion:(CLRegion *)region代理方法反馈相关信息 stopMonitoringForRegion: 停止对某个区域进行定位追踪 requestWhenInUseAuthorization 请求获得应用使用时的定位服务授权注意使用此方法前在要在info.plist中配置NSLocationWhenInUseUsageDescription requestAlwaysAuthorization 请求获得应用一直使用定位服务授权注意使用此方法前要在info.plist中配置NSLocationAlwaysUsageDescription 代理方法 说明 -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations; 位置发生改变后执行第一次定位到某个位置之后也会执行 - (void)locationManager:(CLLocationManager *)manager        didUpdateHeading:(CLHeading *)newHeading; 导航方向发生变化后执行   - (void)locationManager:(CLLocationManager *)manager     didEnterRegion:(CLRegion *)region 进入某个区域之后执行 - (void)locationManager:(CLLocationManager *)manager     didExitRegion:(CLRegion *)region 走出某个区域之后执行 iOS 8 还提供了更加人性化的定位服务选项。App 的定位服务不再仅仅是关闭或打开现在定位服务的启用提供了三个选项「永不」「使用应用程序期间」和「始终」。同时考虑到能耗问题如果一款 App 要求始终能在后台开启定位服务iOS 8 不仅会在首次打开 App 时主动向你询问还会在日常使用中弹窗提醒你该 App 一直在后台使用定位服务并询问你是否继续允许。在iOS7及以前的版本如果在应用程序中使用定位服务只要在程序中调用startUpdatingLocation方法应用就会询问用户是否允许此应用是否允许使用定位服务同时在提示过程中可以通过在info.plist中配置通过配置Privacy - Location Usage Description告诉用户使用的目的同时这个配置是可选的。 但是在iOS8中配置配置项发生了变化可以通过配置NSLocationAlwaysUsageDescription或者NSLocationWhenInUseUsageDescription来告诉用户使用定位服务的目的并且注意这个配置是必须的如果不进行配置则默认情况下应用无法使用定位服务打开应用不会给出打开定位服务的提示除非安装后自己设置此应用的定位服务。同时在应用程序中需要根据配置对requestAlwaysAuthorization或locationServicesEnabled方法进行请求。由于本人机器已经更新到最新的iOS8.1下面的内容主要针对iOS8使用iOS7的朋友需要稍作调整。 // // KCMainViewController.m // CoreLocation //#import KCMainViewController.h #import CoreLocation/CoreLocation.hinterface KCMainViewController ()CLLocationManagerDelegate{CLLocationManager *_locationManager; }endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];//定位管理器_locationManager[[CLLocationManager alloc]init];if (![CLLocationManager locationServicesEnabled]) {NSLog(定位服务当前可能尚未打开请设置打开);return;}//如果没有授权则请求用户授权if ([CLLocationManager authorizationStatus]kCLAuthorizationStatusNotDetermined){[_locationManager requestWhenInUseAuthorization];}else if([CLLocationManager authorizationStatus]kCLAuthorizationStatusAuthorizedWhenInUse){//设置代理_locationManager.delegateself;//设置定位精度_locationManager.desiredAccuracykCLLocationAccuracyBest;//定位频率,每隔多少米定位一次CLLocationDistance distance10.0;//十米定位一次_locationManager.distanceFilterdistance;//启动跟踪定位[_locationManager startUpdatingLocation];} }#pragma mark - CoreLocation 代理 #pragma mark 跟踪定位代理方法每次位置发生变化即会执行只要定位到相应位置 //可以通过模拟器设置一个虚拟位置否则在模拟器中无法调用此方法 -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{CLLocation *location[locations firstObject];//取出第一个位置CLLocationCoordinate2D coordinatelocation.coordinate;//位置坐标NSLog(经度%f,纬度%f,海拔%f,航向%f,行走速度%f,coordinate.longitude,coordinate.latitude,location.altitude,location.course,location.speed);//如果不需要实时定位使用完即使关闭定位服务[_locationManager stopUpdatingLocation]; }end 注意 1.定位频率和定位精度并不应当越精确越好需要视实际情况而定因为越精确越耗性能也就越费电。 2.定位成功后会根据设置情况频繁调用-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations方法这个方法返回一组地理位置对象数组每个元素一个CLLocation代表地理位置信息包含经度、纬度、海报、行走速度等信息之所以返回数组是因为有些时候一个位置点可能包含多个位置。 3.使用完定位服务后如果不需要实时监控应该立即关闭定位服务以节省资源。 4.除了提供定位功能CLLocationManager还可以调用startMonitoringForRegion:方法对指定区域进行监控。 地理编码 除了提供位置跟踪功能之外在定位服务中还包含CLGeocoder类用于处理地理编码和逆地理编码又叫反地理编码功能。 地理编码根据给定的位置通常是地名确定地理坐标(经、纬度)。 逆地理编码可以根据地理坐标经、纬度确定位置信息街道、门牌等。 CLGeocoder最主要的两个方法就是- (void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;和- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;分别用于地理编码和逆地理编码。下面简单演示一下 // // KCMainViewController.m // CoreLocation //#import KCMainViewController.h #import CoreLocation/CoreLocation.hinterface KCMainViewController ()CLLocationManagerDelegate{CLGeocoder *_geocoder; }endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];_geocoder[[CLGeocoder alloc]init];[self getCoordinateByAddress:北京];[self getAddressByLatitude:39.54 longitude:116.28]; }#pragma mark 根据地名确定地理坐标 -(void)getCoordinateByAddress:(NSString *)address{//地理编码[_geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {//取得第一个地标地标中存储了详细的地址信息注意一个地名可能搜索出多个地址CLPlacemark *placemark[placemarks firstObject];CLLocation *locationplacemark.location;//位置CLRegion *regionplacemark.region;//区域NSDictionary *addressDic placemark.addressDictionary;//详细地址信息字典,包含以下部分信息 // NSString *nameplacemark.name;//地名 // NSString *thoroughfareplacemark.thoroughfare;//街道 // NSString *subThoroughfareplacemark.subThoroughfare; //街道相关信息例如门牌等 // NSString *localityplacemark.locality; // 城市 // NSString *subLocalityplacemark.subLocality; // 城市相关信息例如标志性建筑 // NSString *administrativeAreaplacemark.administrativeArea; // 州 // NSString *subAdministrativeAreaplacemark.subAdministrativeArea; //其他行政区域信息 // NSString *postalCodeplacemark.postalCode; //邮编 // NSString *ISOcountryCodeplacemark.ISOcountryCode; //国家编码 // NSString *countryplacemark.country; //国家 // NSString *inlandWaterplacemark.inlandWater; //水源、湖泊 // NSString *oceanplacemark.ocean; // 海洋 // NSArray *areasOfInterestplacemark.areasOfInterest; //关联的或利益相关的地标NSLog(位置:%,区域:%,详细信息:%,location,region,addressDic);}]; }#pragma mark 根据坐标取得地名 -(void)getAddressByLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude{//反地理编码CLLocation *location[[CLLocation alloc]initWithLatitude:latitude longitude:longitude];[_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {CLPlacemark *placemark[placemarks firstObject];NSLog(详细信息:%,placemark.addressDictionary);}]; }end 地图 iOS从6.0开始地图数据不再由谷歌驱动而是改用自家地图当然在国内它的数据是由高德地图提供的。这样一来如果在iOS6.0之前进行地图开发的话使用方法会有所不同基于目前的情况其实使用iOS6.0之前版本的系统基本已经寥寥无几了所有在接下来的内容中不会再针对iOS5及之前版本的地图开发进行介绍。 在iOS中进行地图开发主要有两种方式一种是直接利用MapKit框架进行地图开发利用这种方式可以对地图进行精准的控制另一种方式是直接调用苹果官方自带的地图应用主要用于一些简单的地图应用例如进行导航覆盖物填充等无法进行精确的控制。当然本节重点内容还是前者后面的内容也会稍加提示。 用MapKit之前需要简单了解一下MapKit中地图展示控件MKMapView的的一些常用属性和方法具体如下表 属性 说明 userTrackingMode 跟踪类型是一个枚举 MKUserTrackingModeNone :不进行用户位置跟踪 MKUserTrackingModeFollow :跟踪用户位置 MKUserTrackingModeFollowWithHeading :跟踪用户位置并且跟踪用户前进方向 mapType 地图类型是一个枚举 MKMapTypeStandard :标准地图一般情况下使用此地图即可满足 MKMapTypeSatellite 卫星地图 MKMapTypeHybrid 混合地图加载最慢比较消耗资源 userLocation 用户位置只读属性 annotations 当前地图中的所有大头针只读属性 对象方法 说明 - (void)addAnnotation:(id MKAnnotation)annotation; 添加大头针对应的有添加大头针数组 - (void)removeAnnotation:(id MKAnnotation)annotation; 删除大头针对应的有删除大头针数组 - (void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated; 设置地图显示区域用于控制当前屏幕显示地图范围 - (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated; 设置地图中心点位置 - (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(UIView *)view; 将地理坐标经纬度转化为数学坐标UIKit坐标 - (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view; 将数学坐标转换为地理坐标 - (MKAnnotationView *)dequeueReusableAnnotationViewWithIdentifier:(NSString *)identifier; 从缓存池中取出大头针类似于UITableView中取出UITableViewCell为了进行性能优化而设计 - (void)selectAnnotation:(id MKAnnotation)annotation animated:(BOOL)animated; 选中指定的大头针 - (void)deselectAnnotation:(id MKAnnotation)annotation animated:(BOOL)animated; 取消选中指定的大头针 代理方法 说明 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ; 用户位置发生改变时触发第一次定位到用户位置也会触发该方法 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation ; 显示区域发生改变后触发 - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView; 地图加载完成后触发 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id MKAnnotation)annotation; 显示大头针时触发返回大头针视图通常自定义大头针可以通过此方法进行 - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view 点击选中某个大头针时触发 - (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view 取消选中大头针时触发 - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id MKOverlay)overlay 渲染地图覆盖物时触发 用户位置跟踪 在很多带有地图的应用中默认打开地图都会显示用户当前位置同时将当前位置标记出来放到屏幕中点方便用户对周围情况进行查看。如果在iOS6或者iOS7中实现这个功能只需要添加地图控件、设置用户跟踪模式、在-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation代理方法中设置地图中心区域及显示范围。但是在iOS8中用法稍有不同 1.由于在地图中进行用户位置跟踪需要使用定位功能而定位功能在iOS8中设计发生了变化因此必须按照前面定位章节中提到的内容进行配置和请求。 2.iOS8中不需要进行中心点的指定默认会将当前位置设置中心点并自动设置显示区域范围。 了解以上两点要进行用户位置跟踪其实就相当简单了值得一提的是-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation这个代理方法。这个方法只有在定位利用前面章节中的定位内容到当前位置之后就会调用以后每当用户位置发生改变就会触发调用频率相当频繁。 大头针 在iOS开发中经常会标记某个位置需要使用地图标注也就是大家俗称的“大头针”。只要一个NSObject类实现MKAnnotation协议就可以作为一个大头针通常会重写协议中coordinate标记位置、title标题、subtitle子标题三个属性然后在程序中创建大头针对象并调用addAnnotation:方法添加大头针即可之所以iOS没有定义一个基类实现这个协议供开发者使用多数原因应该是MKAnnotation是一个模型对象对于多数应用模型会稍有不同例如后面的内容中会给大头针模型对象添加其他属性。 KCAnnotation.h // // KCAnnotation.h // MapKit //#import Foundation/Foundation.h #import MapKit/MapKit.hinterface KCAnnotation : NSObjectMKAnnotationproperty (nonatomic) CLLocationCoordinate2D coordinate; property (nonatomic, copy) NSString *title; property (nonatomic, copy) NSString *subtitle;end KCMainViewController.m // // KCMainViewController.m // MapKit Annotation // 37.785834 -122.406417 // 39.92 116.39#import KCMainViewController.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.h #import KCAnnotation.hinterface KCMainViewController ()MKMapViewDelegate{CLLocationManager *_locationManager;MKMapView *_mapView; }endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];[self initGUI]; }#pragma mark 添加地图控件 -(void)initGUI{CGRect rect[UIScreen mainScreen].bounds;_mapView[[MKMapView alloc]initWithFrame:rect];[self.view addSubview:_mapView];//设置代理_mapView.delegateself;//请求定位服务_locationManager[[CLLocationManager alloc]init];if(![CLLocationManager locationServicesEnabled]||[CLLocationManager authorizationStatus]!kCLAuthorizationStatusAuthorizedWhenInUse){[_locationManager requestWhenInUseAuthorization];}//用户位置追踪(用户位置追踪用于标记用户当前位置此时会调用定位服务)_mapView.userTrackingModeMKUserTrackingModeFollow;//设置地图类型_mapView.mapTypeMKMapTypeStandard;//添加大头针[self addAnnotation]; }#pragma mark 添加大头针 -(void)addAnnotation{CLLocationCoordinate2D location1CLLocationCoordinate2DMake(39.95, 116.35);KCAnnotation *annotation1[[KCAnnotation alloc]init];annotation1.titleCMJ Studio;annotation1.subtitleKenshin Cuis Studios;annotation1.coordinatelocation1;[_mapView addAnnotation:annotation1];CLLocationCoordinate2D location2CLLocationCoordinate2DMake(39.87, 116.35);KCAnnotation *annotation2[[KCAnnotation alloc]init];annotation2.titleKenshinKaoru;annotation2.subtitleKenshin Cuis Home;annotation2.coordinatelocation2;[_mapView addAnnotation:annotation2]; }#pragma mark - 地图控件代理方法 #pragma mark 更新用户位置只要用户改变则调用此方法包括第一次定位到用户位置 -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{NSLog(%,userLocation);//设置地图显示范围(如果不进行区域设置会自动显示区域范围并指定当前用户位置为地图中心点)// MKCoordinateSpan spanMKCoordinateSpanMake(0.01, 0.01);// MKCoordinateRegion regionMKCoordinateRegionMake(userLocation.location.coordinate, span);// [_mapView setRegion:region animated:true]; }end 运行效果   设置大头针视图 在一些应用中系统默认的大头针样式可能无法满足实际的需求此时就需要修改大头针视图默认样式。根据前面MapKit的代理方法不难发现- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id MKAnnotation)annotation;方法可以返回一个大头针视图只要实现这个方法并在这个方法中定义一个大头针视图MKAnnotationView对象并设置相关属性就可以改变默认大头针的样式。MKAnnotationView常用属性 属性 说明 annotation 大头针模型信息包括标题、子标题、地理位置。 image 大头针图片 canShowCallout 点击大头针是否显示标题、子标题内容等注意如果在- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id MKAnnotation)annotation;方法中重新定义大头针默认情况是无法交互的需要设置为true。 calloutOffset 点击大头针时弹出详情信息视图的偏移量 selected 是否被选中状态 leftCalloutAccessoryView 弹出详情左侧视图 rightCalloutAccessoryView 弹出详情右侧视图 需要注意 a.这个代理方法的调用时机:每当有大头针显示到系统可视界面中时就会调用此方法返回一个大头针视图放到界面中同时当前系统位置标注也就是地图中蓝色的位置点也是一个大头针也会调用此方法因此处理大头针视图时需要区别对待。 b.类似于UITableView的代理方法此方法调用频繁开发过程中需要重复利用MapKit的缓存池将大头针视图缓存起来重复利用。 c.自定义大头针默认情况下不允许交互如果交互需要设置canShowCallouttrue d.如果代理方法返回nil则会使用默认大头针视图需要根据情况设置。 下面以一个示例进行大头针视图设置这里设置了大头针的图片、弹出视图、偏移量等信息。 KCAnnotation.h // // KCAnnotation.h // MapKit //#import Foundation/Foundation.h #import MapKit/MapKit.hinterface KCAnnotation : NSObjectMKAnnotationproperty (nonatomic) CLLocationCoordinate2D coordinate; property (nonatomic, copy) NSString *title; property (nonatomic, copy) NSString *subtitle;#pragma mark 自定义一个图片属性在创建大头针视图时使用 property (nonatomic,strong) UIImage *image;end KCMainViewController.m // // KCMainViewController.m // MapKit Annotation // 37.785834 -122.406417 // 39.92 116.39#import KCMainViewController.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.h #import KCAnnotation.hinterface KCMainViewController ()MKMapViewDelegate{CLLocationManager *_locationManager;MKMapView *_mapView; }endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];[self initGUI]; }#pragma mark 添加地图控件 -(void)initGUI{CGRect rect[UIScreen mainScreen].bounds;_mapView[[MKMapView alloc]initWithFrame:rect];[self.view addSubview:_mapView];//设置代理_mapView.delegateself;//请求定位服务_locationManager[[CLLocationManager alloc]init];if(![CLLocationManager locationServicesEnabled]||[CLLocationManager authorizationStatus]!kCLAuthorizationStatusAuthorizedWhenInUse){[_locationManager requestWhenInUseAuthorization];}//用户位置追踪(用户位置追踪用于标记用户当前位置此时会调用定位服务)_mapView.userTrackingModeMKUserTrackingModeFollow;//设置地图类型_mapView.mapTypeMKMapTypeStandard;//添加大头针[self addAnnotation]; }#pragma mark 添加大头针 -(void)addAnnotation{CLLocationCoordinate2D location1CLLocationCoordinate2DMake(39.95, 116.35);KCAnnotation *annotation1[[KCAnnotation alloc]init];annotation1.titleCMJ Studio;annotation1.subtitleKenshin Cuis Studios;annotation1.coordinatelocation1;annotation1.image[UIImage imageNamed:icon_pin_floating.png];[_mapView addAnnotation:annotation1];CLLocationCoordinate2D location2CLLocationCoordinate2DMake(39.87, 116.35);KCAnnotation *annotation2[[KCAnnotation alloc]init];annotation2.titleKenshinKaoru;annotation2.subtitleKenshin Cuis Home;annotation2.coordinatelocation2;annotation2.image[UIImage imageNamed:icon_paopao_waterdrop_streetscape.png];[_mapView addAnnotation:annotation2]; }#pragma mark - 地图控件代理方法 #pragma mark 显示大头针时调用注意方法中的annotation参数是即将显示的大头针对象 -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(idMKAnnotation)annotation{//由于当前位置的标注也是一个大头针所以此时需要判断此代理方法返回nil使用默认大头针视图if ([annotation isKindOfClass:[KCAnnotation class]]) {static NSString *key1AnnotationKey1;MKAnnotationView *annotationView[_mapView dequeueReusableAnnotationViewWithIdentifier:key1];//如果缓存池中不存在则新建if (!annotationView) {annotationView[[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:key1];annotationView.canShowCallouttrue;//允许交互点击annotationView.calloutOffsetCGPointMake(0, 1);//定义详情视图偏移量annotationView.leftCalloutAccessoryView[[UIImageView alloc]initWithImage:[UIImage imageNamed:icon_classify_cafe.png]];//定义详情左侧视图}//修改大头针视图//重新设置此类大头针视图的大头针模型(因为有可能是从缓存池中取出来的位置是放到缓存池时的位置)annotationView.annotationannotation;annotationView.image((KCAnnotation *)annotation).image;//设置大头针视图的图片return annotationView;}else {return nil;} } end 运行效果 注意 在MapKit框架中除了MKAnnotationView之外还有一个MKPinAnnotationView它是MKAnnotationView的子类相比MKAnnotationView多了两个属性pinColor和animationDrop分别用于设置大头针视图颜色和添加大头针动画。 扩展--自定义大头针弹详情视图 通过上面的示例不难看出MKAnnotationView足够强大何况还有MKPinAnnotationView很多信息都可以进行设置但是唯独不能修改大头针描述详情视图仅仅支持详情中左右视图内容。要实现这个需求目前开发中普遍采用的思路就是: a.点击一个大头针A时重新在A的坐标处添加另一个大头针B注意此时将A对应的大头针视图canShowCallout设置为false作为大头针详情模型然后在- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id MKAnnotation)annotation;代理方法中判断大头针类型如果是B则重写MKAnnotationView可以自定义一个类C继承于MKAnnotationView返回自定义大头针视图C。 b.定义大头针视图C继承于MKAnnotationView或者MKPinAnnotationView,在自定义大头针视图中添加自己的控件完成自定义布局。 在使用百度地图客户端时当点击一个搜索位置时可以看到此位置的评价等信息视图效果大概如下   下面不妨试着实现一下这个效果 大头针模型KCAnnotation.h // // KCAnnotation.h // MapKit //#import Foundation/Foundation.h #import MapKit/MapKit.hinterface KCAnnotation : NSObjectMKAnnotationproperty (nonatomic) CLLocationCoordinate2D coordinate; property (nonatomic, copy) NSString *title; property (nonatomic, copy) NSString *subtitle;#pragma mark 自定义一个图片属性在创建大头针视图时使用 property (nonatomic,strong) UIImage *image;#pragma mark 大头针详情左侧图标 property (nonatomic,strong) UIImage *icon; #pragma mark 大头针详情描述 property (nonatomic,copy) NSString *detail; #pragma mark 大头针右下方星级评价 property (nonatomic,strong) UIImage *rate;end 弹出详情大头针模型KCCalloutAnnotation.h // // KCCalloutAnnotation.h // MapKit //#import UIKit/UIKit.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.hinterface KCCalloutAnnotation : NSObjectMKAnnotationproperty (nonatomic) CLLocationCoordinate2D coordinate; property (nonatomic, copy,readonly) NSString *title; property (nonatomic, copy,readonly) NSString *subtitle;#pragma mark 左侧图标 property (nonatomic,strong) UIImage *icon; #pragma mark 详情描述 property (nonatomic,copy) NSString *detail; #pragma mark 星级评价 property (nonatomic,strong) UIImage *rate;end 弹出详情大头针视图KCCalloutAnnotatonView.h // // KCCalloutView.h // MapKit // 自定义弹出标注视图#import UIKit/UIKit.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.h #import KCCalloutAnnotation.hinterface KCCalloutAnnotationView : MKAnnotationViewproperty (nonatomic ,strong) KCCalloutAnnotation *annotation;#pragma mark 从缓存取出标注视图 (instancetype)calloutViewWithMapView:(MKMapView *)mapView;end KCCalloutAnnotationView.m // // KCCalloutView.m // MapKit //#import KCCalloutAnnotationView.h #define kSpacing 5 #define kDetailFontSize 12 #define kViewOffset 80interface KCCalloutAnnotationView(){UIView *_backgroundView;UIImageView *_iconView;UILabel *_detailLabel;UIImageView *_rateView; }endimplementation KCCalloutAnnotationView-(instancetype)init{if(self[super init]){[self layoutUI];}return self; } -(instancetype)initWithFrame:(CGRect)frame{if (self[super initWithFrame:frame]) {[self layoutUI];}return self; }-(void)layoutUI{//背景_backgroundView[[UIView alloc]init];_backgroundView.backgroundColor[UIColor whiteColor];//左侧添加图标_iconView[[UIImageView alloc]init];//上方详情_detailLabel[[UILabel alloc]init];_detailLabel.lineBreakModeNSLineBreakByWordWrapping;//[_text sizeToFit];_detailLabel.font[UIFont systemFontOfSize:kDetailFontSize];//下方星级_rateView[[UIImageView alloc]init];[self addSubview:_backgroundView];[self addSubview:_iconView];[self addSubview:_detailLabel];[self addSubview:_rateView]; }(instancetype)calloutViewWithMapView:(MKMapView *)mapView{static NSString *calloutKeycalloutKey1;KCCalloutAnnotationView *calloutView(KCCalloutAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:calloutKey];if (!calloutView) {calloutView[[KCCalloutAnnotationView alloc]init];}return calloutView; }#pragma mark 当给大头针视图设置大头针模型时可以在此处根据模型设置视图内容 -(void)setAnnotation:(KCCalloutAnnotation *)annotation{[super setAnnotation:annotation];//根据模型调整布局_iconView.imageannotation.icon;_iconView.frameCGRectMake(kSpacing, kSpacing, annotation.icon.size.width, annotation.icon.size.height);_detailLabel.textannotation.detail;float detailWidth150.0;CGSize detailSize [annotation.detail boundingRectWithSize:CGSizeMake(detailWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:{NSFontAttributeName: [UIFont systemFontOfSize:kDetailFontSize]} context:nil].size;float detailXCGRectGetMaxX(_iconView.frame)kSpacing;_detailLabel.frameCGRectMake(detailX, kSpacing, detailSize.width, detailSize.height);_rateView.imageannotation.rate;_rateView.frameCGRectMake(detailX, CGRectGetMaxY(_detailLabel.frame)kSpacing, annotation.rate.size.width, annotation.rate.size.height);float backgroundWidthCGRectGetMaxX(_detailLabel.frame)kSpacing;float backgroundHeight_iconView.frame.size.height2*kSpacing;_backgroundView.frameCGRectMake(0, 0, backgroundWidth, backgroundHeight);self.boundsCGRectMake(0, 0, backgroundWidth, backgroundHeightkViewOffset);} end 主视图控制器KCMainViewController.m // // KCMainViewController.m // MapKit Annotation // 37.785834 -122.406417 // 39.92 116.39#import KCMainViewController.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.h #import KCAnnotation.h #import KCCalloutAnnotationView.h #import KCCalloutAnnotationView.hinterface KCMainViewController ()MKMapViewDelegate{CLLocationManager *_locationManager;MKMapView *_mapView; }endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];[self initGUI]; }#pragma mark 添加地图控件 -(void)initGUI{CGRect rect[UIScreen mainScreen].bounds;_mapView[[MKMapView alloc]initWithFrame:rect];[self.view addSubview:_mapView];//设置代理_mapView.delegateself;//请求定位服务_locationManager[[CLLocationManager alloc]init];if(![CLLocationManager locationServicesEnabled]||[CLLocationManager authorizationStatus]!kCLAuthorizationStatusAuthorizedWhenInUse){[_locationManager requestWhenInUseAuthorization];}//用户位置追踪(用户位置追踪用于标记用户当前位置此时会调用定位服务)_mapView.userTrackingModeMKUserTrackingModeFollow;//设置地图类型_mapView.mapTypeMKMapTypeStandard;//添加大头针[self addAnnotation]; }#pragma mark 添加大头针 -(void)addAnnotation{CLLocationCoordinate2D location1CLLocationCoordinate2DMake(39.95, 116.35);KCAnnotation *annotation1[[KCAnnotation alloc]init];annotation1.titleCMJ Studio;annotation1.subtitleKenshin Cuis Studios;annotation1.coordinatelocation1;annotation1.image[UIImage imageNamed:icon_pin_floating.png];annotation1.icon[UIImage imageNamed:icon_mark1.png];annotation1.detailCMJ Studio...;annotation1.rate[UIImage imageNamed:icon_Movie_Star_rating.png];[_mapView addAnnotation:annotation1];CLLocationCoordinate2D location2CLLocationCoordinate2DMake(39.87, 116.35);KCAnnotation *annotation2[[KCAnnotation alloc]init];annotation2.titleKenshinKaoru;annotation2.subtitleKenshin Cuis Home;annotation2.coordinatelocation2;annotation2.image[UIImage imageNamed:icon_paopao_waterdrop_streetscape.png];annotation2.icon[UIImage imageNamed:icon_mark2.png];annotation2.detailKenshin Cui...;annotation2.rate[UIImage imageNamed:icon_Movie_Star_rating.png];[_mapView addAnnotation:annotation2]; }#pragma mark - 地图控件代理方法 #pragma mark 显示大头针时调用注意方法中的annotation参数是即将显示的大头针对象 -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(idMKAnnotation)annotation{//由于当前位置的标注也是一个大头针所以此时需要判断此代理方法返回nil使用默认大头针视图if ([annotation isKindOfClass:[KCAnnotation class]]) {static NSString *key1AnnotationKey1;MKAnnotationView *annotationView[_mapView dequeueReusableAnnotationViewWithIdentifier:key1];//如果缓存池中不存在则新建if (!annotationView) {annotationView[[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:key1]; // annotationView.canShowCallouttrue;//允许交互点击annotationView.calloutOffsetCGPointMake(0, 1);//定义详情视图偏移量annotationView.leftCalloutAccessoryView[[UIImageView alloc]initWithImage:[UIImage imageNamed:icon_classify_cafe.png]];//定义详情左侧视图}//修改大头针视图//重新设置此类大头针视图的大头针模型(因为有可能是从缓存池中取出来的位置是放到缓存池时的位置)annotationView.annotationannotation;annotationView.image((KCAnnotation *)annotation).image;//设置大头针视图的图片return annotationView;}else if([annotation isKindOfClass:[KCCalloutAnnotation class]]){//对于作为弹出详情视图的自定义大头针视图无弹出交互功能canShowCalloutfalse这是默认值在其中可以自由添加其他视图因为它本身继承于UIViewKCCalloutAnnotationView *calloutView[KCCalloutAnnotationView calloutViewWithMapView:mapView];calloutView.annotationannotation;return calloutView;} else {return nil;} }#pragma mark 选中大头针时触发 //点击一般的大头针KCAnnotation时添加一个大头针作为所点大头针的弹出详情视图 -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{KCAnnotation *annotationview.annotation;if ([view.annotation isKindOfClass:[KCAnnotation class]]) {//点击一个大头针时移除其他弹出详情视图 // [self removeCustomAnnotation];//添加详情大头针渲染此大头针视图时将此模型对象赋值给自定义大头针视图完成自动布局KCCalloutAnnotation *annotation1[[KCCalloutAnnotation alloc]init];annotation1.iconannotation.icon;annotation1.detailannotation.detail;annotation1.rateannotation.rate;annotation1.coordinateview.annotation.coordinate;[mapView addAnnotation:annotation1];} }#pragma mark 取消选中时触发 -(void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view{[self removeCustomAnnotation]; }#pragma mark 移除所用自定义大头针 -(void)removeCustomAnnotation{[_mapView.annotations enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {if ([obj isKindOfClass:[KCCalloutAnnotation class]]) {[_mapView removeAnnotation:obj];}}]; } end  在这个过程中需要注意几点 1.大头针A作为一个普通大头针其中最好保存自定义大头针视图C所需要的模型以便根据不同的模型初始化视图。 2.自定义大头针视图C的大头针模型B中不需要title、subtitle属性最好设置为只读模型中最后保存自定义大头针视图C所需要的布局模型数据。 3.只有点击非B类大头针时才新增自定义大头针并且增加时要首先移除其他B类大头针避免重叠一般建议放到取消大头针选择的代理方法中。 4.通常在自定义大头针视图C设置大头针模型时布局界面此时需要注意新增大头针的位置通常需要偏移一定的距离才能达到理想的效果。 运行效果 使用自带的地图应用 除了可以使用MapKit框架进行地图开发对地图有精确的控制和自定义之外如果对于应用没有特殊要求的话选用苹果自带的地图应用也是一个不错的选择。使用苹果自带的应用时需要用到MapKit中的MKMapItem类这个类有一个openInMapsWithLaunchOptions:动态方法和一个openMapsWithItems: launchOptions:静态方法用于打开苹果地图应用。第一个方法用于在地图上标注一个位置第二个方法除了可以标注多个位置外还可以进行多个位置之间的驾驶导航使用起来也是相当方便。在熟悉这两个方法使用之前有必要对两个方法中的options参数做一下简单说明 键(常量) 说明 值 MKLaunchOptionsDirectionsModeKey 路线模式常量 MKLaunchOptionsDirectionsModeDriving  驾车模式 MKLaunchOptionsDirectionsModeWalking 步行模式 MKLaunchOptionsMapTypeKey 地图类型枚举 MKMapTypeStandard 标准模式 MKMapTypeSatellite 卫星模式 MKMapTypeHybrid  混合模式 MKLaunchOptionsMapCenterKey 中心点坐标CLLocationCoordinate2D类型   MKLaunchOptionsMapSpanKey 地图显示跨度MKCoordinateSpan 类型   MKLaunchOptionsShowsTrafficKey 是否 显示交通状况布尔型   MKLaunchOptionsCameraKey 3D地图效果MKMapCamera类型 注意此属性从iOS7及以后可用前面的属性从iOS6开始可用   单个位置的标注 下面的代码演示了如何在苹果自带地图应用上标记一个位置首先根据反地理编码获得一个CLPlacemark位置对象然后将其转换为MKPlacemark对象用于MKMapItem初始化最后调用其openInMapsWithLaunchOptions:打开地图应用并标记 // // KCMainViewController.m // AppleMap //#import KCMainViewController.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.hinterface KCMainViewController () property (nonatomic,strong) CLGeocoder *geocoder; endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];_geocoder[[CLGeocoder alloc]init];[self location]; }#pragma mark 在地图上定位 -(void)location{//根据“北京市”进行地理编码[_geocoder geocodeAddressString:北京市 completionHandler:^(NSArray *placemarks, NSError *error) {CLPlacemark *clPlacemark[placemarks firstObject];//获取第一个地标MKPlacemark *mkplacemark[[MKPlacemark alloc]initWithPlacemark:clPlacemark];//定位地标转化为地图的地标NSDictionary *options{MKLaunchOptionsMapTypeKey:(MKMapTypeStandard)};MKMapItem *mapItem[[MKMapItem alloc]initWithPlacemark:mkplacemark];[mapItem openInMapsWithLaunchOptions:options];}]; } end 运行效果 标记多个位置 如果要标记多个位置需要调用MKMapItem的静态方法下面的代码演示中需要注意使用CLGeocoder进行定位时一次只能定位到一个位置所以第二个位置定位放到了第一个位置获取成功之后。 // // KCMainViewController.m // AppleMap#import KCMainViewController.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.hinterface KCMainViewController () property (nonatomic,strong) CLGeocoder *geocoder; endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];_geocoder[[CLGeocoder alloc]init];[self listPlacemark]; }-(void)listPlacemark{//根据“北京市”进行地理编码[_geocoder geocodeAddressString:北京市 completionHandler:^(NSArray *placemarks, NSError *error) {CLPlacemark *clPlacemark1[placemarks firstObject];//获取第一个地标MKPlacemark *mkPlacemark1[[MKPlacemark alloc]initWithPlacemark:clPlacemark1];//注意地理编码一次只能定位到一个位置不能同时定位所在放到第一个位置定位完成回调函数中再次定位[_geocoder geocodeAddressString:郑州市 completionHandler:^(NSArray *placemarks, NSError *error) {CLPlacemark *clPlacemark2[placemarks firstObject];//获取第一个地标MKPlacemark *mkPlacemark2[[MKPlacemark alloc]initWithPlacemark:clPlacemark2];NSDictionary *options{MKLaunchOptionsMapTypeKey:(MKMapTypeStandard)};//MKMapItem *mapItem1[MKMapItem mapItemForCurrentLocation];//当前位置MKMapItem *mapItem1[[MKMapItem alloc]initWithPlacemark:mkPlacemark1];MKMapItem *mapItem2[[MKMapItem alloc]initWithPlacemark:mkPlacemark2];[MKMapItem openMapsWithItems:[mapItem1,mapItem2] launchOptions:options];}];}]; } end 运行效果 地图导航 要使用地图导航功能在自带地图应用中相当简单只要设置参数配置导航模式即可例如在上面代码基础上设置驾驶模式则地图应用会启动驾驶模式计算两点之间的距离同时对路线进行规划。 // // KCMainViewController.m // AppleMap //#import KCMainViewController.h #import CoreLocation/CoreLocation.h #import MapKit/MapKit.hinterface KCMainViewController () property (nonatomic,strong) CLGeocoder *geocoder; endimplementation KCMainViewController- (void)viewDidLoad {[super viewDidLoad];_geocoder[[CLGeocoder alloc]init];[self turnByTurn]; }-(void)turnByTurn{//根据“北京市”地理编码[_geocoder geocodeAddressString:北京市 completionHandler:^(NSArray *placemarks, NSError *error) {CLPlacemark *clPlacemark1[placemarks firstObject];//获取第一个地标MKPlacemark *mkPlacemark1[[MKPlacemark alloc]initWithPlacemark:clPlacemark1];//注意地理编码一次只能定位到一个位置不能同时定位所在放到第一个位置定位完成回调函数中再次定位[_geocoder geocodeAddressString:郑州市 completionHandler:^(NSArray *placemarks, NSError *error) {CLPlacemark *clPlacemark2[placemarks firstObject];//获取第一个地标MKPlacemark *mkPlacemark2[[MKPlacemark alloc]initWithPlacemark:clPlacemark2];NSDictionary *options{MKLaunchOptionsMapTypeKey:(MKMapTypeStandard),MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving};//MKMapItem *mapItem1[MKMapItem mapItemForCurrentLocation];//当前位置MKMapItem *mapItem1[[MKMapItem alloc]initWithPlacemark:mkPlacemark1];MKMapItem *mapItem2[[MKMapItem alloc]initWithPlacemark:mkPlacemark2];[MKMapItem openMapsWithItems:[mapItem1,mapItem2] launchOptions:options];}];}]; } end 运行效果 注意其实如果不用苹果自带的地图应用也可以实现地图导航MapKit中提供了MKDirectionRequest对象用于计算路线提供了MKDirections用于计算方向这样一来只需要调用MKMapView的addOverlay等方法添加覆盖物即可实现类似的效果有兴趣的朋友可以试一下。 由于定位和地图框架中用到了诸多类有些初学者容易混淆下面简单对比一下。 CLLocation用于表示位置信息包含地理坐标、海拔等信息包含在CoreLoaction框架中。 MKUserLocation一个特殊的大头针表示用户当前位置。 CLPlacemark定位框架中地标类封装了详细的地理信息。 MKPlacemark类似于CLPlacemark只是它在MapKit框架中可以根据CLPlacemark创建MKPlacemark。
http://wiki.neutronadmin.com/news/417901/

相关文章:

  • 泊头网站建设服务云浮市住房城乡建设信息网网站
  • 哪些企业需要网站建设的网站如何引入流量
  • 山东网站建设团队wordpress 备份 教程
  • 如何创立网站泉州网站建设是什么意思
  • 花店网站建设的工作流程怎么改网站模板
  • 成都网站优化外包苏州网站运营公司
  • 汤臣倍健网站建设方案群晖WordPress无端口号
  • 云畅网站建设后台外星人做的网站
  • 1m带宽做网站代做ansys网站
  • 企业网站管理系统哪个好定制旅游网站建设方案
  • 建造师在建设部网站何时更新网页设计与制作用什么软件做
  • 做门户网站怎么赚钱dw做网站小技巧
  • 网站代理违法吗专业网站建设专业网站设计
  • 找人做的网站怎么做网站要学些什么
  • nanopi neo做网站崇信门户网个人留言
  • 公司网站邮箱费用长沙软件开发公司排名
  • 一起做网店官方网站网站建设用宝塔
  • 三合一网站一般多少钱网页界面设计宽度和安全区
  • 一家专门做开网店的网站施工企业质量发展规划
  • 返利网网站框架目录可以帮忙做网站做公司
  • php直播网站开发网站qq联系怎么做
  • 想创业做网站app网站开发定制
  • 建立网站目的c语言可以做网站吗
  • 个人视频网站应该怎么做邓州网站建设
  • 制作企业网站是怎么收费的免费网站建设讯息
  • 赣州建站多个网站如何做301
  • 合肥建站比较便宜的公司广州建立网站
  • seo站群优化技术让网站会员做产品标签确认
  • 定制网站与模板网站的主要区别深圳办公室设计公司排名
  • 婚纱网站建设微信群可以做试卷网站数学试卷小学六