为项目添加定位和导航功能

现在不少App都配备了定位和导航的功能,今天我教大家用iOS原生态的方法来实现这个两个功能。我们通过系统提供的CoreLocation和MapKit来实现。接下来用代码来演示。

1、添加MapView并且实例化它

1
2
3
4
5
6
7
8
MKMapView* myMapView = = [[MKMapView alloc]initWithFrame:self.view.frame];

//让MapView显示当前位置
[myMapView setShowsUserLocation:YES];

//设置代理(MKMapViewDelegate)
myMapView.delegate = self;
[self.view addSubview:myMapView];

2、声明CLLocationManager并且实例化它,实现定位功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CLLocationManager* manager;
if (manager==nil) {
    manager = [[CLLocationManager alloc]init];
    if ([manager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
        [_manager requestWhenInUseAuthorization];

        //设置代理(CLLocationManagerDelegate)
        manager.delegate = self;

        //设置定位精度
        manager.desiredAccuracy = kCLLocationAccuracyBest;

        //设置距离筛选
        manager.distanceFilter = 100;
    }
}
//开始定位
[manager startUpdatingLocation];

注意:使用定位时记得在Info.plist添加NSLocationWhenInUseUsageDescription这个键值

3、实现CLLocationManagerDelegate的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//定位成功的回调
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
  //获取定位成功的经纬度
  CLLocation* location1 = locations.firstObject;
  CLLocationCoordinate2D centerCoordinate2D = location1.coordinate;
  
  //为MapView添加大头针
           MKPointAnnotation* localAnnotstion = [[MKPointAnnotation alloc]init];
  localAnnotstion.coordinate = centerCoordinate2D;
  localAnnotstion.title = @"当前位置";
  [_myMapView addAnnotation:localAnnotstion];
  
  //设置MapView的显示区域
  MKCoordinateRegion region1 = MKCoordinateRegionMakeWithDistance(centerCoordinate2D, 500, 500);
  [myMapView setRegion:[myMapView regionThatFits:region1] animated:YES];
  
  //定位成功就导航,设置导航路线的起点
  MKPlacemark* localPlacemark = [[MKPlacemark alloc]initWithCoordinate:centerCoordinate2D addressDictionary:nil];
  MKMapItem* fromItem = [[MKMapItem alloc]initWithPlacemark:localPlacemark];
  
  //createLineFromCurrentSite是我自己写的方法,用来获取导航路线和获取导航步骤
  //myItem指导航的终点,它实例化参考上面fromItem的实例化
  [self createLineFromCurrentSite:fromItem to:myItem];
  
  //停止定位
  [manager stopUpdatingLocation];

}

//定位失败的回调
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
NSLog(@"guide error is %@",error);
}

4、createLineFromCurrentSite方法的实现,用来用来获取导航路线和获取导航步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-(void)createLineFromCurrentSite:(MKMapItem*) fromItem to:(MKMapItem*)toItem{
  //实例化导航请求
  MKDirectionsRequest* request = [[MKDirectionsRequest alloc]init];
  
  //设置导航的起点和终点
  request.source = fromItem;
  request.destination = toItem;
  
  //为no时只显示一条导航路线
  request.requestsAlternateRoutes = NO;
  
  //实例化MKDirections
  MKDirections* directions = [[MKDirections alloc]initWithRequest:request];
  
  //如果当前导航好没结束,就取消下一次导航请求
  if (directions.calculating) {
      [directions cancel];
  }

  //开始导航,在block里面写回调的方法
  [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse * _Nullable response, NSError * _Nullable error) {
      if (response.routes.count==0|| error) {
      //导航失败
          NSLog(@"directions error is %@",error);
      }else{
      //导航成功
          for (MKRoute* route in response.routes) {
              for (MKRouteStep* step in route.steps) {
               //打印导航的步骤
                NSLog(@"导航:%@", step.instructions);
            }
        //将导航路线添加到MapView上面
        [myMapView addOverlay:route.polyline level:MKOverlayLevelAboveRoads];
        }
    }
  }];
}

5、实现MKMapViewDelegate的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//通过这个方法来帮我们绘制导航路线
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
  if ([overlay isKindOfClass:[MKPolyline class]]) {
      //设置渲染器
      MKPolylineRenderer* renderer = [[MKPolylineRenderer alloc]initWithPolyline:overlay];
      
      //设置线的长度
      [renderer setLineWidth:2];
      
      //设置线的颜色
      [renderer setStrokeColor:[UIColor redColor]];
      return renderer;
}
  return nil;

}

Comments