选择注释图钉时更改图钉颜色 [英] Changing pin color when selecting annotation pin

查看:131
本文介绍了选择注释图钉时更改图钉颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序是一个地图视图,用户可以在其中输入一个地址,该地址将在总部的地图上放置一个紫色图钉.其次,用户可以输入任何地址,这将在地图上显示一个红色的图钉.我希望能够将红色图钉的图钉颜色更改为红色,绿色或紫色.

My app is a map view where the user can enter an address which will put a purple pin on the map for the HQ. Secondly, the user can enter any address, which will put a red pin on the map. I would like to be able to change the pin color of the red pins to either red, green, or purple.

我偶然发现了一个教程,该教程将允许用户选择注释图钉并通过显示模式视图来更改其图钉颜色.我精心遵循了本教程,但是由于某种原因,它无法正常工作.显示与销的选择模态视图,但是当被选择的销的颜色,在地图视图中的销颜色不被更新.另外,我不想使用"png"图像显示自定义图钉,而是要使用内置的标准图钉(因为这就是我所需要的).我该如何调整下面的代码来实现这一目标?我添加了整个代码.

I stumbled across a tutorial that will allow the user to select an annotation pin and change its pin color by displaying a modal view. I followed the tutorial meticulously, but for some reason, it is not working correctly. The modal view with the pin selection is displayed, but when a pin color is selected, the pin color on the map view is not updated. Additionally, instead of using "png" images to display custom pins, I would like to use the built-in standard pins (since that's all I need). How can I adjust my code below to achieve this? I added my entire code.

FieldMapController.m

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

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

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

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方法中.您正确地重用了注解视图,但错误地认为重用的视图配置正确.当您检查视图是否为零时,您仅将全新视图配置为具有与注释名称匹配的图钉颜色.您需要做的是检查它是否为nil,如果是,则创建一个新的并关闭该if.然后确保新注释视图和重用注释视图的针脚颜色,标题,附件视图等都已设置为该注释.

The problem I see is early on in your viewForAnnotation method. You correctly reuse annotationviews but incorrectly assume that the reused view is configured properly. When you check if the view is nil you only configure brand new ones to have the pin colour that matches the annotation's name. What you need to do is check if it is nil, if is then make a new one and close that if. Then make sure both new and reused annotationviews have their pin colour, title, accessory view etc set up as you want it for that annotation.

此外,您不能设置MKPinAnnotationView.image,它将被覆盖.如果您确实要设置自定义图像,则必须使用常规的MKAnnotationView.如果可以使用标准的红色,绿色和蓝色引脚,则只需将.pinColor设置为所需的任何值即可.

Also you can't set the .image of an MKPinAnnotationView, it'll just get overwritten. If you really want to set a custom image you have to use a regular MKAnnotationView. If you are ok with using the standard red, green and blue pins then just set the .pinColor to whatever you want.

这篇关于选择注释图钉时更改图钉颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆