iOS原生地图热点搜索和基本使用汇总

来源:互联网 发布:电视的mac地址怎么查 编辑:程序博客网 时间:2024/05/22 16:04

1. 创建之前的准备工作

  1.1  在Info.plist文件中添加下面两句话

  NSLocationAlwaysUsageDescription —> 确定定位吗?亲
  //请求的授权,除了可以在APP打开时允许定位服务,也可以在APP进入后台仍然可以使用定位服务(永久) --> 与上边一个可以二选一
  [_locationManager requestAlwaysAuthorization];
  NSLocationWhenInUseUsageDescripyion —>需要定位吗?
  //此方法请求的授权,仅限于用户在打开使用APP时允许使用系统的定位服务(在应用使用期间)
  [_locationManager requestWhenInUseAuthorization];

  1.2  导入库文件 MapKit.framework 和 CoreLocation.framework
2. 工程创建说明 ---> 使用系统自带的MKPointAnnotation、MKPinAnnotationView 及自定义  MKPointAnnotation、MKPinAnnotationView 

  以下是ViewController.m 文件

  2.1 viewDidLoad 中的加载

复制代码
 1 #import "ViewController.h" 2 #import "MapKit/MapKit.h" 3 #import "MyPointAnnotation.h" 4 #import "MyAnnotationView.h" 5  6 @interface ViewController ()<MKMapViewDelegate> { 7      8     MKMapView *_mapView;    //地图对象 9     UILabel *_userLocationLable; //查看用户坐标10 }11 12 @end13 14 @implementation ViewController15 16 - (void)viewDidLoad {17     [super viewDidLoad];18     19     //调用创建地图视图的方法20     [self createMapView];21     //调用创建大头针的方法22     [self createAnnotations];23     //调用这个方法调用所有的覆盖层的方法24     [self overLay];25     //调用创建UI的方法26     [self createUI];27 }28 29 @end
复制代码

  2.2 创建地图视图的方法

复制代码
  1 //创建地图视图的方法  2 - (void)createMapView {  3     //创建地图对象  4     _mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];  5     //设置map的类型 或地图模式  6     _mapView.mapType = MKMapTypeStandard;  7     /*  8      MKMapTypeStandard = 0, 纸张地图 标准地图  9      MKMapTypeSatellite,    纯卫星地图 10      MKMapTypeHybrid,       混合式地图 描述的卫星图 11      */ 12     //设置map的初始位置 13     //创建地理坐标2D 需要经度和纬度 如:经度:120.366486 纬度:36.083743 14     CLLocationCoordinate2D location = CLLocationCoordinate2DMake(36.083743, 120.366486); 15     //起始时 锁定一个矩形为1000 X 1000米的方位 ,坐标点location 16     _mapView.region = MKCoordinateRegionMakeWithDistance(location, 1000, 1000); 17     //设置地图能否放大缩小 18     _mapView.zoomEnabled = YES; 19     //设置地图能否滚动 20     _mapView.scrollEnabled = YES; 21     //设置显示用户的位置  先判断是否开始了定位服务 22     if ([CLLocationManager locationServicesEnabled] == YES) { 23         //显示用户的位置 24         _mapView.showsUserLocation = YES; 25         //设置用户的基本跟踪状态 26         [_mapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:YES]; 27          28         /* 29          MKUserTrackingModeNone = 0,        不尾随 一般不设 30          MKUserTrackingModeFollow,      尾随用户位置,地图保存正向(北方向) 31          MKUserTrackingModeFollowWithHeading 随着地图旋转而尾随(地图方向和设备方向同步) 32          */ 33     } 34     //设置代理 需遵守MKMapViewDelegate代理协议 35     _mapView.delegate = self; 36     //将地图加入到self.view上 37     [self.view addSubview:_mapView]; 38 } 39  40 #pragma mark - 地图协议中的方法 - 41 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { 42      43     //这里判断必须要加,这个方法在刷新时会将用户的位置也会传到这个方法里,所以需要判断,如果不是大头针就是用户坐标点(蓝点),如果是蓝点(用户坐标点) 直接返回nil 44     if ([annotation isKindOfClass:[MKPointAnnotation class]] == NO) { 45         return nil; 46     } 47      48     //调用系统的方法 49 //    MKPinAnnotationView *annotationView = [self systemMethodWithMapView:mapView andAnnotation:annotation]; 50      51     //调用自定义的方法 52     MKPinAnnotationView *annotationView = [self customMethodWithMapView:mapView andAnnotation:annotation]; 53      54     return annotationView; 55 } 56  57 //自定义的方法 58 - (MKPinAnnotationView *)customMethodWithMapView:(MKMapView *)mapView andAnnotation:(MKPointAnnotation *)annotation { 59     MyAnnotationView *annotationView = (MyAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotationView"]; 60      61     if (annotationView == nil) { 62          63          64         annotationView = [[MyAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"CustomAnnotationView"]; 65          66     }else { 67          68         annotationView.annotation = annotation; 69     } 70      71      72      73     return annotationView; 74 } 75  76  77 //系统方法 78 - (MKPinAnnotationView *)systemMethodWithMapView:(MKMapView *)mapView andAnnotation:(MKPointAnnotation *)annotation { 79      80     //    类似于tableview的复用机制那个方法 81     MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"AnnotationView"]; 82     if (annotationView == nil) { 83         //如果从队列取 没有的话,需要创建新的大头针视图 84         annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"AnnotationView"]; 85         //设置大头针的色彩,默认是红色,还有绿色和紫色(了解) 86         annotationView.pinColor = MKPinAnnotationColorPurple; 87         //设置允许显示气泡(重要) 88         annotationView.canShowCallout = YES; 89         //设置下坠动画 (从上往下掉下来) 默认为NO 90         annotationView.animatesDrop = YES; 91         //设置是佛可以拖拽 92         annotationView.draggable = YES; 93          94     }else { 95          96         //如果有空闲,拿队列里空闲的view 然后显示大头针 97         annotationView.annotation = annotation; 98          99     }100     return annotationView;101 }
复制代码

  2.3  创建大头针的方法

复制代码
 1 //创建大头针的方法 2 - (void)createAnnotations { 3     //创建大头针1 4     MKPointAnnotation *annotation1 = [[MKPointAnnotation alloc] init]; 5     //设置title 6     annotation1.title = @"不知道是哪"; 7     //设置子title 8     annotation1.subtitle = @"真不知道是哪儿"; 9     //设置大头针的经纬度坐标10     annotation1.coordinate = CLLocationCoordinate2DMake(-39.89, -79.88);11     //把大头针1加入到地图上12     [_mapView addAnnotation:annotation1];13     //创建大头针214     MKPointAnnotation *annotation2 = [[MKPointAnnotation alloc] init];15     annotation2.title = @"南半球";16     annotation2.subtitle = @"真是南半球";17     annotation2.coordinate = CLLocationCoordinate2DMake(-80.89, 156.456);18     [_mapView addAnnotation:annotation2];19     //自定义方式创建大头针320     MyPointAnnotation *annotation3 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(40.5, -88.7) title:@"第一个位置" subTitle:@"这里风景优美" information:@"这里是国家级旅游景点"];21     //自定义方式创建大头针422     MyPointAnnotation *annotation4 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(37.68, -96.54) title:@"第二个位置" subTitle:@"这里有点冷" information:@"世界冰展所在地"];23     //将大头针3和4一块加入到地图上  用addAnnotations24     [_mapView addAnnotations:@[annotation3,annotation4]];25     26     //将地图滚动到大头针3的位置27     _mapView.centerCoordinate = annotation1.coordinate;28  29 }
复制代码

  2.4 这个方法调用所有的覆盖层的方法

复制代码
  1 //这个方法调用所有的覆盖层的方法  2 - (void)overLay {  3       4     //调用绘制线的方法  5     [self pathOverLay];  6       7     //调用多边形图层的方法  8     [self polyOverlay];  9      10     //调用绘制圆的图层的方法 11     [self circleOverlay]; 12      13 } 14  15 //绘制圆的图层的方法 16 - (void)circleOverlay { 17     //圆图层和annotation一样需要添加到地图上,每个图层绘制都需要实现管理图层方法 18     CLLocationCoordinate2D centerLocation = CLLocationCoordinate2DMake(37.68, -96.54); 19     //绘制圆 20     MKCircle *circleOverlay = [MKCircle circleWithCenterCoordinate:centerLocation radius:100000]; 21     //添加到地图上 22     [_mapView addOverlay:circleOverlay]; 23      24 } 25  26 //多边形图层的方法 27 - (void)polyOverlay { 28     //设置多边形的角的坐标,记住一定要首尾相连 29      30     CLLocationCoordinate2D ploycoords[5]  = { 31         CLLocationCoordinate2DMake(35.443, -77.876), 32         CLLocationCoordinate2DMake(36.553, -77.976), 33         CLLocationCoordinate2DMake(35.553, -79.567), 34         CLLocationCoordinate2DMake(34.443, -79.567), 35         CLLocationCoordinate2DMake(35.443, -77.876) 36          37          38     }; 39      40     MKPolygon *polygonOverlay = [MKPolygon polygonWithCoordinates:ploycoords count:5]; 41     //添加到地图上 42     [_mapView addOverlay:polygonOverlay]; 43 } 44  45 //绘制线的方法 46 - (void)pathOverLay { 47     CLLocationCoordinate2D pathCoords[6] = { 48          49         CLLocationCoordinate2DMake(33.123, -77.456), 50         CLLocationCoordinate2DMake(34.123, -78.456), 51         CLLocationCoordinate2DMake(32.123, -79.456), 52         CLLocationCoordinate2DMake(36.123, -71.456), 53         CLLocationCoordinate2DMake(35.123, -70.456), 54         CLLocationCoordinate2DMake(36.123, 73.456) 55          56     }; 57      58     //创建图层 59     MKPolyline *pathOverlay = [MKPolyline polylineWithCoordinates:pathCoords count:6]; 60     //添加到地图上 61     [_mapView addOverlay:pathOverlay]; 62      63      64 } 65  66 //管理图层视图 67 - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay { 68      69     if ([overlay isKindOfClass:[MKPolyline class]] == YES) { 70         MKPolylineRenderer *line = [[MKPolylineRenderer alloc] initWithOverlay:overlay]; 71         //线的宽度 72         line.lineWidth = 2; 73         //设置线的颜色 74         line.strokeColor = [UIColor blueColor]; 75          76         return line; 77          78     }else if ([overlay isKindOfClass:[MKPolygon class]] == YES) { 79          80         MKPolygonRenderer *poly = [[MKPolygonRenderer alloc] initWithOverlay:overlay]; 81         //设置线宽 82         poly.lineWidth = 1; 83         //设置边缘颜色 84         poly.strokeColor = [UIColor greenColor]; 85         //设置填充颜色 86         poly.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.5]; 87          88         return poly; 89          90     }else if ([overlay isKindOfClass:[MKCircle class]] == YES) { 91          92         //创建圆视图 所有的视图都是overlay添加到构造方法参数 93         MKCircleRenderer *circle = [[MKCircleRenderer alloc] initWithOverlay:overlay]; 94         //设置边缘宽度 95         circle.lineWidth = 1; 96         //设置边缘颜色 97         circle.strokeColor = [UIColor redColor]; 98         //设置填充颜色 透明度0.4 99         circle.fillColor = [[UIColor greenColor] colorWithAlphaComponent:0.4];100         101         return circle;102     }103     104     return nil;105 }
复制代码

  2.5  创建UI的方法 在创建该方法之前需要在AppDelegate.m 文件中将ViewController包装成导航控制器

复制代码
  1 //创建UI的方法  2 - (void)createUI {  3       4     _userLocationLable = [[UILabel alloc] initWithFrame:CGRectMake(0, 64, 320, 80)];  5     [self.view addSubview:_userLocationLable];  6     //创建BarButtonItem 这个是用户定位(跟随),参数放入一个MapView类型的地图对象  7     MKUserTrackingBarButtonItem *item = [[MKUserTrackingBarButtonItem alloc] initWithMapView:_mapView];  8     //设置导航左边的BarButtonItem  9     self.navigationItem.leftBarButtonItem = item; 10      11     UIButton *hotSearchButton = [UIButton buttonWithType:UIButtonTypeCustom]; 12     hotSearchButton.frame = CGRectMake(0, 64, 100, 40); 13     [hotSearchButton setTitle:@"热点搜索" forState:UIControlStateNormal]; 14      15     [hotSearchButton addTarget:self action:@selector(hotSeatch) forControlEvents:UIControlEventTouchUpInside]; 16      17      18     [hotSearchButton  setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 19      20     [self.view addSubview:hotSearchButton]; 21      22      23     UIButton *keywordSearchButton = [UIButton buttonWithType:UIButtonTypeCustom]; 24      25     keywordSearchButton.frame = CGRectMake(100, 64, 100, 40); 26      27     [keywordSearchButton setTitle:@"关键字搜索" forState:UIControlStateNormal]; 28      29     [keywordSearchButton addTarget:self action:@selector(keywordSearch) forControlEvents:UIControlEventTouchUpInside]; 30     [keywordSearchButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 31      32     [self.view addSubview:keywordSearchButton]; 33      34     //添加一个长按的手势 用长按的手势添加大头针 35     UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; 36     longPress.minimumPressDuration = 1; 37     //长按手势加入到地图 38     [_mapView addGestureRecognizer:longPress]; 39 } 40  41 //长按手势执行的方法 42 - (void)longPress:(UILongPressGestureRecognizer *)longPress { 43     //注:一定别忘了判断 44     //判断长按手势状态 如果是开始的状态,就执行判断题 45     if (longPress.state == UIGestureRecognizerStateBegan) { 46         //在地图上找到CGPoint坐标(屏幕坐标) 47         CGPoint point = [longPress locationInView:_mapView]; 48         //屏幕坐标转成经纬度坐标 49         CLLocationCoordinate2D coordinate = [_mapView convertPoint:point toCoordinateFromView:_mapView]; 50         //创建大头针 51          52         MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:coordinate title:@"手势加入" subTitle:@"长按手势" information:@"长按手势信息"]; 53          54  55         //加入到地图上 56         [_mapView addAnnotation:annotation]; 57          58     } 59      60      61 } 62  63  64 - (void)hotSeatch { 65     //创建本地搜索请求 66     MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc] init]; 67     //设置搜索热点词(自然语言) 68     request.naturalLanguageQuery = @"学校"; 69     //设置搜索范围,以某个原点为中心,向外扩展一段经纬度距离范围 70     CLLocationCoordinate2D origionpoint = CLLocationCoordinate2DMake(36.08397, 120.37126); 71     //设置经纬度跨越范围 72     MKCoordinateSpan span = MKCoordinateSpanMake(0.3, 0.3); 73     //设置经纬度搜索区域 74     MKCoordinateRegion region = MKCoordinateRegionMake(origionpoint, span); 75     //将区域赋值给搜索请求对象中的region属性中 76     request.region = region; 77     //将地图移动到该区域 78     [_mapView setRegion:region]; 79      80     //创建本地搜索对象 81     MKLocalSearch *search = [[MKLocalSearch alloc] initWithRequest:request]; 82     //开启搜索 83     [search startWithCompletionHandler:^(MKLocalSearchResponse * _Nullable response, NSError * _Nullable error) { 84          85         if (error == nil) { 86              87             //搜索成功 88             //获取搜索结果 89             NSArray *arrResult = response.mapItems; 90              91             for (MKMapItem *item in arrResult) { 92                  93                 //先取出地图目的坐标对象(标记) 94                 MKPlacemark *placeMark = item.placemark; 95                 /* 96                  地标里存放的经纬度,以及位置的地理信息说明,如名字、街道等等 97                  */ 98                 //创建大头针 99                 MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:placeMark.location.coordinate title:placeMark.name subTitle:placeMark.locality information:placeMark.locality];100                 101                 //加入到地图中102                 [_mapView addAnnotation:annotation];103             }104             105             106         }else {107             NSLog(@"搜索失败");108             109         }110         111     }];112     113 }114 115 //关键字搜索116 - (void)keywordSearch {117     //创建地理编码118     CLGeocoder *geocoder = [[CLGeocoder alloc] init];119     //正向地理编码120     [geocoder geocodeAddressString:@"青岛科技大学" completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {121         122         if (error == nil) {123             //解析地理位置成功124             //成功后遍历数组125             for (CLPlacemark *place in placemarks) {126                 127                 //创建大头针128                 129                 MyPointAnnotation *annotation = [[MyPointAnnotation alloc] initWithCoorDinate:place.location.coordinate title:place.name subTitle:place.locality information:place.locality];130                 //将大头针加入到地图131                 [_mapView addAnnotation:annotation];132                 133             }134             135         }else {136             137             NSLog(@"正向地理编码解析失败");138         }139         140         141     }];142     143 }144 145 146 //完成更新用户定位147 - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {148     149     150     _userLocationLable.text = [NSString stringWithFormat:@"用户位置: %.5f, %.5f",userLocation.coordinate.latitude, userLocation.coordinate.longitude];151     NSLog(@"%@",_userLocationLable.text);152     153 }
复制代码

3. 自定义 MyPointAnnotation 工程如下:

复制代码
 1 MyPointAnnotation.h文件 2  3 #import <MapKit/MapKit.h> 4  5 @interface MyPointAnnotation : MKPointAnnotation 6  7 /** 大头针信息  */ 8 @property(nonatomic, copy) NSString *information; 9 10 //构造方法11 - (id)initWithCoorDinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title subTitle:(NSString *)subTitle information:(NSString *)information;12 13 @end14 15 MyPointAnnotation.m文件16 17 #import "MyPointAnnotation.h"18 19 @implementation MyPointAnnotation20 21 - (id)initWithCoorDinate:(CLLocationCoordinate2D)coordinate title:(NSString *)title subTitle:(NSString *)subTitle information:(NSString *)information {22     23     if (self = [super init]) {24         //标题25         self.title = title;26         //子标题27         self.subtitle = subTitle;28         //坐标29         self.coordinate = coordinate;30         //信息31         self.information = information;32     }33     return self;34 }35 36 @end
复制代码

4. 自定义 MyAnnotationView工程如下:

复制代码
 1 MyAnnotationView.h文件 2 #import <MapKit/MapKit.h> 3 #import "MyPointAnnotation.h" //导入自定义的大头针 4 @interface MyAnnotationView : MKPinAnnotationView { 5      6     MyPointAnnotation *myPointAnnotation; 7      8 } 9 10 //静态图片需要继承这个11 //@interface MyAnnotationView : MKAnnotationView {12 //    MyPointAnnotation *myPointAnnotation;13 //}14 15 @end16 17 18 MyAnnotationView.m文件19 #import "MyAnnotationView.h"20 21 @implementation MyAnnotationView22 23 - (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {24     if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {25         //保存参数-传过来的大头针26         myPointAnnotation = annotation;27         28         //创建图片29         UIImage *image = [UIImage imageNamed:@"pink"];30         31         //这种方式只适合静态图片 ,不适合动态和拖拽动态功能,它们有冲突 需要更改一下.h文件中的继承32         //这种方式继承MKAnnotationView 否则没有效果33         //        NSData *imageData = UIImagePNGRepresentation(image);34         //        //处理imageData 比例535         //        image = [UIImage imageWithData:imageData scale:5];36         //        //修改当前视图的大小37         //        self.frame = CGRectMake(0, 0, 40, 40);38         //        //设置图片39         //        self.image = image;40         //        //设置填充模式 按比例填满41         //        self.contentMode = UIViewContentModeScaleToFill;42         43         44         UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(-15, -5, 45, 45)];45         imageView.image = image;46         [self addSubview:imageView];47         48         //允许气泡弹出49         self.canShowCallout = YES;50         //拖拽51         self.draggable = YES;52         //下坠动画53         self.animatesDrop = YES;54         55         56         UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeInfoDark];57         [leftButton addTarget:self action:@selector(leftButton) forControlEvents:UIControlEventTouchUpInside];58         //设置左边访问view59         self.leftCalloutAccessoryView = leftButton;60         61         UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeContactAdd];62         [rightButton addTarget:self action:@selector(rightButton) forControlEvents:UIControlEventTouchUpInside];63         //设置右边访问view64         self.rightCalloutAccessoryView = rightButton;65         66     }67     return self;68 }69 70 71 - (void)leftButton {72     NSLog(@"leftButton:%@",myPointAnnotation.title);73 }74 75 - (void)rightButton {76     NSLog(@"rightButton:%@",myPointAnnotation.information);77 }78 79 @end
0 0
原创粉丝点击