在第三步的基础上,让ViewController实现地图的协议
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation该协议方法类似于UITableView的 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath这个方法,用于返回注解视图。
MKMapViewDelegate,并设置地图MKMapView的代理为该ViewControlelr,
self.mapView.delegate = self;编译一个实现地图注解协议 MKAnnotation的类,如下:
CustomAnnotation.h
// // CustomAnnotation.h // LBS_002_mapview // // Created by liqun on 13-7-25. // Copyright (c) 2013年 Block Cheng. All rights reserved. // #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface CustomAnnotation : NSObject<MKAnnotation> @property (nonatomic, assign, readonly) CLLocationCoordinate2D coordinate; @property (nonatomic, copy, readonly) NSString *title; @property (nonatomic, copy, readonly) NSString *subtitle; - (id) initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle; @end
CustomAnnotation.m
// // CustomAnnotation.m // LBS_002_mapview // // Created by liqun on 13-7-25. // Copyright (c) 2013年 Block Cheng. All rights reserved. // #import "CustomAnnotation.h" @implementation CustomAnnotation - (void)dealloc { [_subtitle release]; [_title release]; [super dealloc]; } - (id) initWithCoordinates:(CLLocationCoordinate2D)paramCoordinates title:(NSString *)paramTitle subTitle:(NSString *)paramSubTitle { if (self = [super init]) { _coordinate = paramCoordinates; _title = [paramTitle copy]; _subtitle = [paramSubTitle copy]; } return self; } @end控制器实现文件的如下:
// // ViewController.m // LBS_002_mapview // // Created by liqun on 13-7-25. // Copyright (c) 2013年 Block Cheng. All rights reserved. // #import "ViewController.h" #import <MapKit/MapKit.h> #import "CustomAnnotation.h" @interface ViewController ()<CLLocationManagerDelegate,MKMapViewDelegate> @property (nonatomic,retain)MKMapView* mapView; @property (nonatomic,retain)CLLocationManager* locationManager; @property (nonatomic,retain)CLLocation* location; @property (nonatomic, retain) CLGeocoder *myGeocoder; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; MKMapView* map = [[MKMapView alloc] initWithFrame:self.view.frame]; map.mapType = MKMapTypeStandard; map.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; [self.view addSubview:map]; [map release]; self.mapView = map; self.mapView.delegate = self; UIButton *addBt = [UIButton buttonWithType:UIButtonTypeRoundedRect]; addBt.frame = CGRectMake(0, 00, 320, 50); [addBt setTitle:@"locationMe" forState:UIControlStateNormal]; [ addBt addTarget:self action:@selector(handleLocationMe:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview: addBt]; if ([CLLocationManager locationServicesEnabled]){ self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; self.locationManager.purpose = @"To provide functionality based on user's current location."; [self.locationManager startUpdatingLocation]; } else { /* Location services are not enabled. Take appropriate action: for instance, prompt the user to enable location services */ NSLog(@"Location services are not enabled"); } self.myGeocoder = [[CLGeocoder alloc] init]; } - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { MKAnnotationView *result = nil; if ([annotation isKindOfClass:[CustomAnnotation class]] == NO){ return result; } if ([mapView isEqual:self.mapView] == NO){ /* We want to process this event only for the Map View that we have created previously */ return result; } /* First, typecast the annotation for which the Map View has fired this delegate message */ CustomAnnotation *senderAnnotation = (CustomAnnotation *)annotation; /* Using the class method we have defined in our custom annotation class, we will attempt to get a reusable identifier for the pin we are about to create */ NSString *pinReusableIdentifier =@"cn.live@helloclq"; /* Using the identifier we retrieved above, we will attempt to reuse a pin in the sender Map View */ MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:pinReusableIdentifier]; if (annotationView == nil){ /* If we fail to reuse a pin, then we will create one */ annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:senderAnnotation reuseIdentifier:pinReusableIdentifier]; /* Make sure we can see the callouts on top of each pin in case we have assigned title and/or subtitle to each pin */ [annotationView setCanShowCallout:YES]; annotationView.draggable = YES; // annotationView.enabled = YES; } //自定义图片时,不能用drop annotationView.animatesDrop = YES; // UIImage *img = [UIImage imageNamed:@"color_3.png"]; // annotationView.image = img; result = annotationView; return result; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(IBAction)handleLocationMe:(id)sender { [self.myGeocoder reverseGeocodeLocation:self.location completionHandler:^(NSArray *placemarks, NSError *error) { if (error == nil &&[placemarks count] > 0){ CLPlacemark *placemark = [placemarks objectAtIndex:0]; /* We received the results */ NSLog(@"Country = %@", placemark.country); NSLog(@"Postal Code = %@", placemark.postalCode); NSLog(@"Locality = %@", placemark.locality); NSLog(@"dic = %@", placemark.addressDictionary ); NSLog(@"dic FormattedAddressLines= %@", [placemark.addressDictionary objectForKey:@"FormattedAddressLines"]); NSLog(@"dic Name = %@", [placemark.addressDictionary objectForKey:@"Name"]); NSLog(@"dic State = %@", [placemark.addressDictionary objectForKey:@"State"]); NSLog(@"dic Street = %@", [placemark.addressDictionary objectForKey:@"Street"]); NSLog(@"dic SubLocality= %@", [placemark.addressDictionary objectForKey:@"SubLocality"]); NSLog(@"dic SubThoroughfare= %@", [placemark.addressDictionary objectForKey:@"SubThoroughfare"]); NSLog(@"dic Thoroughfare = %@", [placemark.addressDictionary objectForKey:@"Thoroughfare"]); CLLocationCoordinate2D location = CLLocationCoordinate2DMake(self.location.coordinate.latitude, self.location.coordinate.longitude); /* Create the annotation using the location */ CustomAnnotation *annotation =[[CustomAnnotation alloc] initWithCoordinates:location title:placemark.name subTitle:placemark.thoroughfare]; [self.mapView addAnnotation:annotation]; [annotation release]; } else if (error == nil && [placemarks count] == 0){ NSLog(@"No results were returned."); } else if (error != nil){ NSLog(@"An error occurred = %@", error); } }]; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ /* We received the new location */ NSLog(@"Latitude = %f", newLocation.coordinate.latitude); NSLog(@"Longitude = %f", newLocation.coordinate.longitude); self.location = newLocation; } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ /* Failed to receive user's location */ } - (void)dealloc { self.mapView = nil; self.location = nil; self.locationManager = nil; [super dealloc]; } @end运行后,点击按钮,效果如下:
点击该注解: