Mapkit中的iOS Pin颜色问题 [英] iOS Pin color issue in mapkit

查看:88
本文介绍了Mapkit中的iOS Pin颜色问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要我的注释有两种颜色.为此,我使用了以下代码,

I want my annotations in two colors. For that I have used following code,

- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id <MKAnnotation>)annotation {  
    static NSString *identifier = @"MyLocation";
    if ([annotation isKindOfClass:[PlaceMark class]]) {
        MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        @try {
            if (annotationView == nil) {
                annotationView = [[MKPinAnnotationView alloc]
                                  initWithAnnotation:annotation
                                  reuseIdentifier:identifier];
            } else {
                annotationView.annotation = annotation;
                
                if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])
                {
                    annotationView.pinColor = MKPinAnnotationColorRed;
                }
                else 
                {
                    annotationView.pinColor = MKPinAnnotationColorGreen;
                }
            }
        }
        @catch (NSException *exception) {
            NSLog(@"nsCenterOrOffice exception = %@",exception);
        }
        return annotationView;
    }
    return nil;
}

但是我仍然无法为所需的注释设置所需的颜色.有时特定的注释图钉颜色为红色,有时为绿色.我不明白为什么会这样.有谁能够帮我 ?谢谢...

But still I am not able to set desired color for desired annotation. Sometimes particular annotation pin color is red and sometimes it's green. I am not getting why this is happening. Can anybody help me ? Thanks...

我正在修改我的代码.这是我更新后的代码

I rework on my code..this is my updated code

MapAnnotation.h

MapAnnotation.h

    #import <MapKit/MapKit.h>
    #import <Foundation/Foundation.h>

    @interface MapAnnotation : MKPointAnnotation
    {
        NSString *title;
        NSString *subtitle;
        int dealLnk;
        float latitude;
        float longitude;
        
        CLLocationCoordinate2D coordinate;
    }

    @property (nonatomic, copy) NSString *title;
    @property (nonatomic, copy) NSString *subtitle;
    @property (nonatomic, assign) int dealLnk;
    @property (nonatomic, assign) float latitude;
    @property (nonatomic, assign) float longitude;
    @property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

    - (id)initWithTitle:(NSString *)ttl subTitle:(NSString *)subttl dealLink:(int)dealLnk latitude:(float)latitude longitude:(float)longitude andCoordinate:(CLLocationCoordinate2D)c2d;
@end

MapAnnotation.m

MapAnnotation.m

#import "MapAnnotation.h"

@implementation MapAnnotation

@synthesize title,subtitle,dealLnk,coordinate,latitude,longitude;

- (id)initWithTitle:(NSString *)ttl subTitle:(NSString *)subttl dealLink:(int)z latitude:(float)latitude1 longitude:(float)longitude1 andCoordinate:(CLLocationCoordinate2D)c2d {
    title = ttl;
    subtitle = subttl;
    dealLnk =z;
    coordinate = c2d;
    longitude = longitude1;
    latitude = latitude1;
    
    return self;
}
@end

这是我的实现文件

-(void)startAddingAnnotation
{
    @try {
        CLLocationCoordinate2D annotationCoord;
        
        z=0;
        for (int i=0; i < [nslatitude count] ; i++,z++)
        {
            
            MapAnnotation  *dealAnnotation   = [[MapAnnotation  alloc] init];
            
            dealAnnotation.dealLnk = z;
            annotationCoord.latitude =  (CGFloat) [[nslatitude objectAtIndex:i] floatValue];
            annotationCoord.longitude = (CGFloat)[[nslongitude objectAtIndex:i] floatValue];
            dealAnnotation.coordinate = annotationCoord;
            
            dealAnnotation.title = [nsCenterName objectAtIndex:i];
            dealAnnotation.subtitle = [nsCenterAddress objectAtIndex:i];
            
            NSLog(@"latitude = %f",dealAnnotation.latitude);
            NSLog(@"longitude = %f",dealAnnotation.longitude);
            
            NSLog(@"dealAnnotation.dealLnk = %d",dealAnnotation.dealLnk);
            NSLog(@"dz = %d",z);
            [mapView addAnnotation:dealAnnotation];
           
        }
        
    }
    @catch (NSException *exception) {
        
        NSLog(@"Exception = %@",exception);
    }
    
    cord.longitude = -112.05186;
    cord.latitude = 33.46577;
    
    MKCoordinateRegion region;
    region.center = cord;
    
    MKCoordinateSpan span = {.latitudeDelta = 1.0, .longitudeDelta = 1.0};
    region.span = span;
    
    [mapView setRegion:region];
    
    
}

#pragma mark - MapView_Delegate
- (MKAnnotationView *)mapView:(MKMapView *)sender viewForAnnotation:(id <MKAnnotation>)annotation {
    

    MapAnnotation *annotation1 = (MapAnnotation *)annotation;
    z = annotation1.dealLnk;
    
      NSLog(@"annotation1.longitude = %f",annotation1.latitude);
      NSLog(@"annotation1.longitude = %f",annotation1.longitude);
    
    if(z<[nslatitude count])
    {
        MKAnnotationView *pinView = nil;
        static NSString *defaultPinID = @"pin1";
        
        pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
        
      
        if ( pinView == nil )
            pinView = [[MKAnnotationView alloc]
                       initWithAnnotation:annotation1 reuseIdentifier:defaultPinID];
        pinView.canShowCallout = YES;
        
        @try {
            
            if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])
            {
                pinView.image = [UIImage imageNamed:@"flag1.png"];
            }
            else
            {
                pinView.image = [UIImage imageNamed:@"flag2.png"];
            }
            pinView.annotation = annotation1;
            pinView.tag = [[nsCenterName objectAtIndex:z] intValue];
            
        }
        @catch (NSException *exception) {
            NSLog(@"nsCenterOrOffice exception = %@",exception);
        }
        
        UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        [rightButton setTitle:annotation.title forState:UIControlStateNormal];
        [pinView setRightCalloutAccessoryView:rightButton];

        return pinView;
    }
    else
    {
        return nil;
    }
    
}

现在的问题是,所有注释都指向不同的位置.我不明白为什么会这样吗? der我的代码有什么问题吗?

Now the problem is, all the annotations are pointing some different location. I am not getting why this is happening? Is der anything wrong in my code?

推荐答案

确定图钉颜色的条件是基于此委托方法的数据 outside ,并且不能保证它会出现在与为特定注释调用此委托方法时同步.

The condition that determines the pin color is based on data outside of this delegate method and there is no guarantee that it will be in sync with when this delegate method is called for a particular annotation.


在这种if条件下:


In this if condition:

if([[nsCenterOrOffice objectAtIndex:z] isEqualToString:@"C"])

z变量显然是在此委托方法外部声明和设置的实例变量(可能恰好在添加注释之前).

the z variable is apparently some instance variable declared and set (probably right before adding an annotation) outside this delegate method.

同样,不能保证在添加注释后将立即调用viewForAnnotation委托方法.也不能保证每个注释只对委托方法调用一次. 因此z值可能与调用委托方法的 current annotation不对应.

Again, there is no guarantee that the viewForAnnotation delegate method will be called immediately after an annotation is added. There is also no guarantee that the delegate method will be called only once for each annotation. So it's possible that the z value does not correspond to the current annotation that the delegate method is being called for.

很有可能在调用addAnnotation之后很好地调用委托方法,将以与添加注释不同的顺序来调用委托方法,并且对于每个注释将多次调用该方法(例如, .(如果用户平移或缩放地图,则注释会重新显示).

It is very possible for the delegate method to be called well after addAnnotation is called, that it will be called in a different order than the annotations were added, and that it will be called multiple times for each annotation (eg. if user pans or zooms the map and annotations come back into view).


要解决此问题,请将"is center or office"属性添加到Placemark类本身,并在创建注释和之前调用addAnnotation时设置该属性.然后,在viewForAnnotation方法中,可以将annotation参数强制转换为Placemark并访问该属性以实现该条件.例如:


To fix this, add the "is center or office" property to the Placemark class itself and set that property when creating the annotation and before calling addAnnotation. Then, in the viewForAnnotation method, you can cast the annotation parameter as a Placemark and access the property to implement the condition. For example:

//where you create and add the annotation:
Placemark *pm = [[Placemark alloc...
pm.coordinate = ...
pm.title = ...
pm.centerOrOffice = [nsCenterOrOffice objectAtIndex:z];
[mapView addAnnotation:pm];


//in viewForAnnotation:
Placemark *myPlacemark = (Placemark *)annotation;
if ([myPlacemark.centerOrOffice isEqualToString:@"C"])
...


一个单独的,不相关的问题是注释视图创建逻辑不太正确.
该代码两次调用initWithAnnotation,实际上第二个initWithAnnotation从未调用,因为第一次调用将始终成功.


A separate, unrelated issue is that the annotation view creation logic is not quite right.
The code calls initWithAnnotation twice and in actuality the second initWithAnnotation never gets called since the first call will always succeed.

您可能想要的是先调用dequeueReusableAnnotationViewWithIdentifier:,然后,如果返回nil,请调用initWithAnnotation.

What you probably wanted was to first call dequeueReusableAnnotationViewWithIdentifier: and then, if that returns nil, call initWithAnnotation.

重组viewForAnnotation中的代码时,请确保将设置pinColor 的代码放在批注视图的出队/初始位置之外(例如,紧接在return annotationView;之前)正确处理重用的视图.

When restructuring the code in viewForAnnotation, be sure to put the code that sets the pinColor outside the dequeue/init of the annotation view (eg. right before the return annotationView;) to properly handle reused views.

这篇关于Mapkit中的iOS Pin颜色问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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