了解一下解析的意思是什么。点击之后,会将下面显示的纬度和经度转换解析为一个地址名称(会显示在哪个国家)。这个操作是靠上一篇文章中在 BLFiveViewController.h 中的属性 @property(nonatomic, strong) CLGeocoder *geocoder;来实现的。(即地理位置的编码器) 方法如下 在 .m 文件中:
- (void)reversButtonClicked:(id)sender
{
self.geocoder = [[CLGeocoder alloc] init];
[self.geocoder reverseGeocoderLocation:self.currentLocation // 将当前定位出来之后的位置传入,下一个参数是一个block 代码块
completionHandler:^(NSArray *placemarks, NSError *error) {// 这个符号 ^ 开头代表时一个 block 后面是 block 的参数,就是传入位置后会有一个代理回调,里面输入的就是代理要做的事情(比设置代理要更加简单)
if (error) { // 解析失败
NSLog(@"%@", error.description);
} else {
if ([placemarks count] > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0] // 一般只有一个坐标,所以解析出来也就一个实例
_locationLabel.text = placemark.country; // CLPlacemark 里面封装了很多属性,比如国家,国家代码,邮政编码,行政区域等等。根据需要选择
}
}
}];
}
接下来了解一下 block,如何定义 block, 然后就是如何调用 block :
typedef void (^UserInfoBlock)(NSString *); // 前半部分是 block名字,后面是参数类型
- (void)test:(UserInfoBlock)uBlock
{
uBlock(@"abc")
}
// 下面就是调用到 block
- (void)reversButtonClicked:(id)sender
{
[self test:^(NSString *name) {
NSLog(@"%@",name);
};]
......
}
下面需要了解一下声明是标柱,标柱其时就是 annotation ,它需要这些内容:坐标 coordinate(这是一个必选的代理方法,title & subtitle是可选的代理方法), title(徐汇区), subtitle(南丹路),还可以扩充一个 index的下标(这是项目中扩充的内容).
首先,其实需要用到标注的话,需要先封装标注的类,上面的一段内容已经介绍了,下面是封装的代码演示,这个类的名称叫做 BLAnnotation .h & BLAnnotation.m :
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface BLAnnotation: NSObject<MKAnnotation>
@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
@property(nonatomic, copy) NSString *title;
@property(nonatomic, copy) NSString *subtitle;
@property(nonatomic, assign) NSInteger index;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
title:(NSString *)title
subtitle:(NSString *)subtitle
index:(NSInteger)index;
@end
实现文件中是这样的:
#import "BLAnnotation.h"
@implementation BLAnnotatiom
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
title:(NSString *)title
subtitle:(NSString *)subtitle
index:(NSInteger)index;
{
self = [super init]
if (self) {
self.coordinate = coordinate;
self.title = title;
self.subtitle = subtitle;
self.index = index;
}
return self;
}
@end
封装好之后的类需要数据才能生成对象,项目中老师在网上寻找到了三个地址的数据,输入必要的参数之后将它们放在了一个可变数组之中,在 BLFiveViewController.m 的 viewDidLoad() 方法中输入如下:
_annotations = [[NSMutableArray alloc] initWithCapacity:3]; // 创建地址库的一个实例对象,它的库存暂时可存放3个地址
// 接下来将这个三个坐标所对应的地址信息写入并在随后添加到刚创建的地址库当中
CLLocationCoordinate2D coordinate1 = {31.19434, 121.43203};
BLAnnotation *annotation1 = [[BLAnnotation alloc] initWithCoordinate:coordinate1 title:@"徐汇区" subtitle:@"广元西路" index:0];
[_annotation addObject:annotation1];
CLLocationCoordinate2D coordinate2 = {31.19190, 121.43304};
BLAnnotation *annotation2 = [[BLAnnotation alloc] initWithCoordinate:coordinate1 title:@"徐汇区" subtitle:@"东方曼哈顿" index:1];
[_annotation addObject:annotation2];
CLLocationCoordinate2D coordinate3 = {31.19223, 121.42847};
BLAnnotation *annotation3 = [[BLAnnotation alloc] initWithCoordinate:coordinate1 title:@"徐汇区" subtitle:@"南丹路" index:2];
[_annotation addObject:annotation3];
在需要完成添加标注的功能,必须在所在类,实现添加标注的协议(_mapView.delegate = self;)。然后就是添加标注的方法,添加标注首先需要移出以前留下的标注信息,然后再添加:
- (void)flagButtonClicked:(id)sender
{
[_mapView removeAnnotations:_mapView.annotations];
[_mapView addAnnotations:_annotations];
}
但是这两个方法还是不够的,因为一旦调用 addAnnotations: 这个方法,系统还会去调用 MKMapViewDelegate 这个代理方法,所以真正完成标注并且显示的是在这个代理方法中完成。代码如下 :
#pragma mark - MKMapViewDelegate methods
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if (![[annotation class) isSubclassOfClass:[BLAnnotation class]]) { // 首先判断输入其中的是不是 BLAnnotation 对象,不是返回 nil
return nil;
}
}
}
(未完待续)