Setting Map Pin colour dynamically for iOS

泄露秘密 提交于 2019-12-11 01:59:41

问题


I parse an xml that contains the string 0 ,1 and 2.

//For reference 0 = Green 1 = Red 2 = Purple

I have a class that confirms to the MKAnnotaion that contains the below variables that are properties.

CLLocationCoordinate2D  coordinate;
NSString            *title;
NSString            *subtitle;
MKPinAnnotationColor pinColor;

This class is named MyAnnotation

Now in the viewDidLoad of the map view I run a for loop to iterate over the parsed data like the below (locationArray holds this data and I pull out all the info just fine.

 for (int i = 0; i < locationArray.count; i++) {
    myAnnotation =[[MyAnnotation alloc] init];

    NSString *thePointName = [[locationArray objectAtIndex:i]xmlName];
    NSString *theAddress = [[locationArray objectAtIndex:i]xmlAddress];

    NSString *latString = [[locationArray objectAtIndex:i]xmlLat];
    NSString *lonString = [[locationArray objectAtIndex:i]xmlLon];

//This is the string that pulls out the mentioned 0, 1 or 2 strings which represent the colour of the pins poinType is retained as a string

    pointType = [[locationArray objectAtIndex:i]xmlType];

    double theLatitude = [latString doubleValue];
    double theLongtitude = [lonString doubleValue];

    userLocation.latitude=theLatitude;
    userLocation.longitude=theLongtitude;

    myAnnotation.coordinate=userLocation;
    myAnnotation.title=[NSString stringWithFormat:@"%@", thePointName];
    myAnnotation.subtitle=[NSString stringWithFormat:@"%@", theAddress];

    //I log that the points are actually giving either of the colors and if so set MyAnnotation class to the pincolor 

    NSLog(@"Points Color %@", pointType);
    if ([pointType isEqualToString:@"0"]){
        myAnnotation.pinColor = MKPinAnnotationColorGreen;
    }else if ([pointType isEqualToString:@"1"]){
        myAnnotation.pinColor = MKPinAnnotationColorRed;
    }else if ([pointType isEqualToString:@"2"]) {
        myAnnotation.pinColor = MKPinAnnotationColorPurple;
    }

    [mapView addAnnotation:myAnnotation];

    }

Now in the MKAnnotationView view i do the below

  - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id     <MKAnnotation>)annotation

 {

// if it's the user location, just return nil.
    if ([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

// try to dequeue an existing pin view first
static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[MKPinAnnotationView alloc]
                                  initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;

    //set pin color to the correct colour
    if (myAnnotation.pinColor = MKPinAnnotationColorGreen) {
    pinView.pinColor = MKPinAnnotationColorGreen;
    }

    else if (myAnnotation.pinColor = MKPinAnnotationColorRed) {
    pinView.pinColor = MKPinAnnotationColorRed;

     }

    else if (myAnnotation.pinColor = MKPinAnnotationColorPurple){
    pinView.pinColor = MKPinAnnotationColorPurple;
    }



    UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
[rightButton addTarget:self
                action:@selector(showDetails:)
      forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = rightButton;


    UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage  imageNamed:@"Profile.png"]];
pinView.leftCalloutAccessoryView = profileIconView;

return pinView;
  }

I have also tried in the above method however it is not setting the pin colours. Everything else is fine!

    //set pin color to the correct colour
    if (pointType isEqualToString:@"0") {
    pinView.pinColor = MKPinAnnotationColorGreen;
    }

    else if (pointType isEqualToString:@"1") {
    pinView.pinColor = MKPinAnnotationColorRed;

    }

    else if (pointType isEqualToString:@"2"){
    pinView.pinColor = MKPinAnnotationColorPurple;
    }

回答1:


This code in viewForAnnotation:

if (myAnnotation.pinColor = MKPinAnnotationColorGreen) {

will not work for two reasons:

  1. It is using a single equals sign which is for assignment -- not for checking equality. It needs to use two equal signs to check for equality. However, this doesn't fix the main issue which is reason #2...

  2. The code is checking the value of myAnnotation which is a variable set outside this delegate method. There is no guarantee that the delegate method will be called in sync with the for-loop in which myAnnotation is set. Do not assume that viewForAnnotation will be called right after you call addAnnotation. It is even possible for the delegate method to be called multiple times for the same annotation if the map view needs to display the annotation again after a zoom or pan.

Instead, you must use the annotation parameter that is passed to the delegate method. This is a reference to the annotation the map view wants a view for in the current call of the delegate method.

Since the annotation parameter is typed generically as id<MKAnnotation>, you'll first have to cast it to your custom class and then you can access any custom properties:

//first make sure this annotation is our custom class before casting it...
if ([annotation isKindOfClass:[MyAnnotation class]])
{
    MyAnnotation *currentAnn = (MyAnnotation *)annotation;

    if (currentAnn.pinColor == MKPinAnnotationColorGreen) {
        pinView.pinColor = MKPinAnnotationColorGreen;
    }

    else if (currentAnn.pinColor == MKPinAnnotationColorRed) {
        pinView.pinColor = MKPinAnnotationColorRed;

    }

    else if (currentAnn.pinColor == MKPinAnnotationColorPurple) {
        pinView.pinColor = MKPinAnnotationColorPurple;
    }
}

or even simpler:

//first make sure this annotation is our custom class before casting it...
if ([annotation isKindOfClass:[MyAnnotation class]])
{
    MyAnnotation *currentAnn = (MyAnnotation *)annotation;        
    pinView.pinColor = currentAnn.pinColor;
}

(Unrelated, but why is the code setting the title of rightButton even though it won't be visible?)



来源:https://stackoverflow.com/questions/13522198/setting-map-pin-colour-dynamically-for-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!