select注释引脚时更改引脚颜色

我的应用程序是一个地图视图,用户可以input一个地址,在地图上为总部添加一个紫色的针。 其次,用户可以input任何地址,这将在地图上放置一个红色的针脚。 我希望能够将红色引脚的引脚颜色更改为红色,绿色或紫色。

我偶然发现了一个教程,允许用户select一个注释引脚,并通过显示一个模态视图来改变它的引脚颜色。 我仔细地跟着教程,但由于某种原因,它不能正常工作。 将显示带有select针的模式视图,但是当select针颜色时,不会更新地图视图上的针颜色。 此外,而不是使用“PNG”图像来显示自定义引脚,我想使用内置的标准引脚(因为这是我所需要的)。 我如何调整我的代码来达到这个目的? 我添加了我的整个代码。

FieldMapController.m

#import "FieldMapController.h" #import "CustomAnnotation.h" #define HQ_latitude @"headquarters_latitude" #define HQ_longitude @"headquarters_longitude" #define HQ_coordinates @"headquarters_coordinates" #import "PinSelectionViewController.h" @interface FieldMapController () @end @implementation FieldMapController @synthesize mapView; @synthesize searchBar; @synthesize geocoder = _geocoder; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } //ACCESS SAVED DATA FROM NSUSERDEFAULTS -(void)viewWillAppear:(BOOL)animated{ NSUserDefaults *uDefaults = [NSUserDefaults standardUserDefaults]; if ([uDefaults boolForKey:@"headquarters_coordinates"]) { CLLocationCoordinate2D savedCoordinate; savedCoordinate.latitude = [uDefaults doubleForKey:@"headquarters_latitude"]; savedCoordinate.longitude = [uDefaults doubleForKey:@"headquarters_longitude"]; NSLog(@"Your HQ is at coordinates %f and %f",savedCoordinate.latitude, savedCoordinate.longitude); CustomAnnotation *annHq =[[CustomAnnotation alloc] init]; annHq.title=@"HQ"; annHq.subtitle=@""; annHq.coordinate= savedCoordinate; [mapView addAnnotation:annHq]; MKCoordinateRegion viewRegion = {{0.0, 0.0}, {0.0, 0.0}}; viewRegion.center.latitude = savedCoordinate.latitude; viewRegion.center.longitude = savedCoordinate.longitude; viewRegion.span.longitudeDelta = 0.5f; viewRegion.span.latitudeDelta = 0.5f; [self.mapView setRegion:viewRegion animated:YES]; [self.mapView setDelegate:self]; } } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.mapView.delegate = self; self.searchBar.delegate = self; //SEARCH BAR TOOLBAR WITH "DONE" AND "CANCEL" BUTTON UIToolbar* searchToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 50)]; searchToolbar.barStyle = UIBarStyleBlackTranslucent; searchToolbar.items = [NSArray arrayWithObjects: [[UIBarButtonItem alloc]initWithTitle:@"Cancel" style:UIBarButtonItemStyleBordered target:self action:@selector(cancelSearchBar)], [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], nil]; [searchToolbar sizeToFit]; searchBar.inputAccessoryView = searchToolbar; } //WHEN PUSHING THE "CANCEL" BUTTON IN THE SEARCH BAR -(void)cancelSearchBar { [searchBar resignFirstResponder]; searchBar.text = @""; } //PREPARE SEGUE FOR THE PIN SELECTOR VIEW -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if([segue.identifier isEqualToString:@"ShowPinChoicesSegue"]) { PinSelectionViewController *pinVC = [segue destinationViewController]; CustomAnnotation *selectedAnnotation = (CustomAnnotation *)sender; pinVC.currentPinType = selectedAnnotation.pinType; pinVC.delegate = self; } } //WHAT HAPPENS WHEN THE "SEARCH" BUTTON AT THE SEARCH BAR KEYBOARD IS TAPPED - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { //Forward Geocoder if (!self.geocoder) { self.geocoder = [[CLGeocoder alloc] init]; } NSString *address = [NSString stringWithFormat:@"%@", self.searchBar.text]; [self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) { if ([placemarks count] > 0) { CLPlacemark *placemark = [placemarks objectAtIndex:0]; CLLocation *location = placemark.location; CLLocationCoordinate2D coordinate = location.coordinate; //Display Coordinates in Console NSLog (@"%f %f", coordinate.latitude, coordinate.longitude); MKCoordinateRegion region; MKCoordinateSpan span; span.latitudeDelta = 0.01; span.longitudeDelta = 0.01; region.span = span; region.center = coordinate; //Create Annotation with Callout Bubble that displays "No Information" MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; [annotation setCoordinate:coordinate]; [annotation setTitle:@"No Information"]; [[self mapView] addAnnotation:annotation]; [self.mapView setRegion:region animated:TRUE]; [self.mapView regionThatFits:region]; //Dismiss the Search Bar Keyboard [self.searchBar resignFirstResponder]; //Delete text in Search Bar self.searchBar.text = @""; } }]; } //CUSTOM ANNOTATION VIEW - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { if ([annotation isKindOfClass:[MKUserLocation class]]) { return nil; } if ([annotation isKindOfClass:[CustomAnnotation class]]) { MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:((CustomAnnotation *)annotation).annotationViewImageName]; if(annotationView == nil) { MKPinAnnotationView *customPinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:((CustomAnnotation *)annotation).annotationViewImageName]; if([[customPinView.annotation title] isEqualToString:@"HQ"]) { //The pin for the HQ should be purple customPinView.pinColor = MKPinAnnotationColorPurple; } else { //All other new pins should be "red" by default customPinView.image = [UIImage imageNamed:((CustomAnnotation *)annotation).annotationViewImageName]; } customPinView.canShowCallout = YES; customPinView.animatesDrop = YES; //Right Callout Accessory Button UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; customPinView.rightCalloutAccessoryView = rightButton; return customPinView; } else { annotationView.annotation = annotation; } return annotationView; } return nil; } //SHOW ACCESSORY VIEW WHEN BUTTON ON CALLOUT BUBBLE IS TAPPED -(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control { if (![view.annotation isKindOfClass:[CustomAnnotation class]]) return; CustomAnnotation *customAnnotation = (CustomAnnotation *)view.annotation; if (control.tag == 0) { [self performSegueWithIdentifier:@"ShowPinChoicesSegue" sender:customAnnotation]; } else { [self onRightCalloutAccessoryViewTouched:control]; } } -(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { if(![view.annotation isKindOfClass:[CustomAnnotation class]]) return; if (!view.rightCalloutAccessoryView) { UIButton *rightViewButton = [[UIButton alloc] initWithFrame:CGRectMake(0.0, 0.0, 48.0, 32.0)]; [rightViewButton addTarget:self action:@selector(onRightCalloutAccessoryViewtouched:) forControlEvents:UIControlEventTouchUpInside]; rightViewButton.tag = 1; view.rightCalloutAccessoryView = rightViewButton; } } -(void)onRightCalloutAccessoryViewTouched:(id)sender { CustomAnnotation *selectedAnnotation = (CustomAnnotation *)[mapView.selectedAnnotations objectAtIndex:0]; [self performSegueWithIdentifier:@"ShowPinChoicesSegue" sender:selectedAnnotation]; } - (void)viewDidUnload { self.mapView = nil; self.searchBar = nil; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } //BUTTON TO SELECT NEW HQ - (IBAction)selectHq:(UIBarButtonItem *)sender { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Select Headquarters" message:@"Enter Address" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil]; alert.alertViewStyle = UIAlertViewStylePlainTextInput; [[alert textFieldAtIndex:0] setKeyboardType:UIKeyboardTypeDefault]; [alert show]; } //REMOVING ALL PINS EXCEPT USER LOCATION - (IBAction)resetPins:(UIBarButtonItem *)sender { id userLocation = [mapView userLocation]; NSMutableArray *pins = [[NSMutableArray alloc] initWithArray:[mapView annotations]]; if ( userLocation != nil ) { [pins removeObject:userLocation]; //avoid removing user location } [mapView removeAnnotations:pins]; pins = nil; [[NSUserDefaults standardUserDefaults] removeObjectForKey:HQ_coordinates]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:HQ_longitude]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:HQ_latitude]; } //ALERT VIEW TO ENTER ADDRESS OF HQ - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex != alertView.cancelButtonIndex) { UITextField *field = [alertView textFieldAtIndex:0]; field.placeholder = @"Enter HQ Address"; if (!self.geocoder) { self.geocoder = [[CLGeocoder alloc] init]; } NSString *hqAddress = [NSString stringWithFormat:@"%@", field.text]; [self.geocoder geocodeAddressString:hqAddress completionHandler:^(NSArray *placemarks, NSError *error) { if ([placemarks count] > 0) { CLPlacemark *placemark = [placemarks objectAtIndex:0]; CLLocation *location = placemark.location; CLLocationCoordinate2D hqCoordinate = location.coordinate; NSLog (@"Your new HQ is at coordinates %f and %f", hqCoordinate.latitude, hqCoordinate.longitude); MKCoordinateRegion region; MKCoordinateSpan span; span.latitudeDelta = 0.01; span.longitudeDelta = 0.01; region.span = span; region.center = hqCoordinate; MKPointAnnotation *hqAnnotation = [[MKPointAnnotation alloc] init]; [hqAnnotation setCoordinate:hqCoordinate]; [hqAnnotation setTitle:@"HQ"]; [[self mapView] addAnnotation:hqAnnotation]; [self.mapView setRegion:region animated:TRUE]; [self.mapView regionThatFits:region]; //Save to NSUserDefaults NSUserDefaults *uDefaults = [NSUserDefaults standardUserDefaults]; [uDefaults setDouble:hqCoordinate.latitude forKey:HQ_latitude]; [uDefaults setDouble:hqCoordinate.longitude forKey:HQ_longitude]; [uDefaults setBool:YES forKey:HQ_coordinates]; [uDefaults synchronize]; } }]; } else { //any actions for "Cancel" } } //DEFINES WHAT SELECTING THE NEW PIN COLOR DOES -(void)userDidSelectPinType:(AnnotationPinType)aPinType { CustomAnnotation *selectedAnnotation = (CustomAnnotation *)[mapView.selectedAnnotations objectAtIndex:0]; selectedAnnotation.pinType = aPinType; [mapView removeAnnotation:selectedAnnotation]; [mapView addAnnotation:selectedAnnotation]; [self.navigationController dismissViewControllerAnimated:YES completion:nil]; } @end 

CustomAnnotation.m

 #import "CustomAnnotation.h" #import <CoreLocation/CoreLocation.h> @implementation CustomAnnotation @synthesize title, subtitle, coordinate; @synthesize pinType; -(id) initWithCoordinate:(CLLocationCoordinate2D)aCoordinate title:(NSString *)aTitle subtitle:(NSString *)aSubtitle { if ((self = [super init])) { self.title = aTitle; self.coordinate = aCoordinate; self.subtitle = aSubtitle; } return self; } - (NSString *)annotationViewImageName { switch (self.pinType) { case 0: return @"Red_Pin.png"; break; case 1: return @"Green_Pin.png"; break; case 2: return @"Purple_Pin.png"; break; default: break; } } - (NSString *)title { return title; } - (NSString *)subtitle { return subtitle; } @end 

PinSelectionViewController.m

 #import "PinSelectionViewController.h" @interface PinSelectionViewController () @end @implementation PinSelectionViewController @synthesize delegate; @synthesize currentPinType; - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - Table view data source - (void)tableView:(UITableView *) tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.row ==currentPinType) cell.accessoryType = UITableViewCellAccessoryCheckmark; } #pragma mark - Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [self.delegate userDidSelectPinType:indexPath.row]; } @end 

PinSelectionDelegateProtocol.h

 #import <Foundation/Foundation.h> typedef enum { RED_PIN, GREEN_PIN, PURPLE_PIN } AnnotationPinType; @protocol PinSelectionDelegate <NSObject> @required -(void)userDidSelectPinType:(AnnotationPinType)aPinType; @end 

我看到的问题早在viewForAnnotation方法中。 您正确地重新使用注释查看,但错误地认为重新使用的视图configuration正确。 当您检查视图是否为零时,您只能configuration全新的视图以使其颜色与注释名称匹配。 你需要做的是检查是否为零,如果是的话再做一个新的closures。 然后确保新注释和重新使用的注释视图的注释颜色,标题,附件视图等都可以根据您的需要进行设置。

你也不能设置.imageMKPinAnnotationView ,它会被覆盖。 如果你真的想设置自定义图像,你必须使用普通的MKAnnotationView。 如果您可以使用标准的红色,绿色和蓝色引脚,那么只需将.pinColor设置为任何你想要的。