您的位置:首页 > 移动开发 > IOS开发

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

2016-11-07 17:13 447 查看
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 @end
13
14 @implementation ViewController
15
16 - (void)viewDidLoad {
17     [super viewDidLoad];
18
19     //调用创建地图视图的方法
20     [self createMapView];
21     //调用创建大头针的方法
22     [self createAnnotations];
23     //调用这个方法调用所有的覆盖层的方法
24     [self overLa
24000
y];
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     //创建大头针2
14     MKPointAnnotation *annotation2 = [[MKPointAnnotation alloc] init];
15     annotation2.title = @"南半球";
16     annotation2.subtitle = @"真是南半球";
17     annotation2.coordinate = CLLocationCoordinate2DMake(-80.89, 156.456);
18     [_mapView addAnnotation:annotation2];
19     //自定义方式创建大头针3
20     MyPointAnnotation *annotation3 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(40.5, -88.7) title:@"第一个位置" subTitle:@"这里风景优美" information:@"这里是国家级旅游景点"];
21     //自定义方式创建大头针4
22     MyPointAnnotation *annotation4 = [[MyPointAnnotation alloc] initWithCoorDinate:CLLocationCoordinate2DMake(37.68, -96.54) title:@"第二个位置" subTitle:@"这里有点冷" information:@"世界冰展所在地"];
23     //将大头针3和4一块加入到地图上  用addAnnotations
24     [_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 @end
14
15 MyPointAnnotation.m文件
16
17 #import "MyPointAnnotation.h"
18
19 @implementation MyPointAnnotation
20
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 @end
16
17
18 MyAnnotationView.m文件
19 #import "MyAnnotationView.h"
20
21 @implementation MyAnnotationView
22
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 比例5
35         //        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         //设置左边访问view
59         self.leftCalloutAccessoryView = leftButton;
60
61         UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
62         [rightButton addTarget:self action:@selector(rightButton) forControlEvents:UIControlEventTouchUpInside];
63         //设置右边访问view
64         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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息