0

注釈を 2 色で表示したい。そのために、次のコードを使用しました。

- (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;
}

しかし、それでも、目的の注釈に目的の色を設定できません。特定の注釈ピンの色が赤の場合もあれば、緑の場合もあります。なぜこれが起こっているのかわかりません。誰でも私を助けることができますか?ありがとう...

私は自分のコードを作り直しました..これは私の更新されたコードです

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

#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;
    }
    
}

問題は、すべての注釈が別の場所を指していることです。なぜこれが起こっているのかわかりませんか?私のコードに何か問題がありますか?

4

2 に答える 2

1

ピンの色を決定する条件は、このデリゲート メソッドの外部のデータに基づいており、特定の注釈に対してこのデリゲート メソッドが呼び出されたときに同期されるという保証はありません。


このif状態では:

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

変数は明らかに、zこのデリゲート メソッドの外部で宣言および設定された (おそらく注釈を追加する直前に) インスタンス変数です。

繰り返しますが、アノテーションが追加された直後にデリゲート メソッドが呼び出されるという保証はありません。viewForAnnotationまた、各アノテーションに対してデリゲート メソッドが 1 回だけ呼び出されるという保証もありません。 そのため、デリゲート メソッドが呼び出されている現在の値に対応しない可能性があります。z annotation

が呼び出された後にデリゲート メソッドが呼び出される可能性が非常にaddAnnotation高く、注釈が追加された順序とは異なる順序で呼び出され、注釈ごとに複数回呼び出される可能性があります (たとえば、ユーザーがパンまたはズームした場合)。マップと注釈が再び表示されます)。


これを修正するには、「is center or office」プロパティをPlacemarkクラス自体に追加し、注釈の作成時およびを呼び出す前にaddAnnotationそのプロパティを設定します。次に、メソッドでパラメータを としてviewForAnnotationキャストし、プロパティにアクセスして条件を実装できます。例えば:annotationPlacemark

//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"])
...


別の無関係な問題は、注釈ビューの作成ロジックが正しくないことです。
コードはinitWithAnnotation2 回呼び出しますが、実際にはinitWithAnnotation、最初の呼び出しは常に成功するため、2 回目は呼び出されません。

おそらくあなたが望んでいたのは、最初に を呼び出しdequeueReusableAnnotationViewWithIdentifier:、それが を返す場合はnilを呼び出すことinitWithAnnotationでした。

のコードを再構築するときは、再利用されたビューを適切に処理するために、アノテーション ビューの dequeue/init の外側(たとえば、 の直前) をviewForAnnotation設定するコードを配置してください。pinColor return annotationView;

于 2013-07-30T12:59:43.430 に答える
0

あなたはいくつかの外部変数にviewForAnnotation依存しています. これらの変数をどのように設定しているかを示すまで、私たちは確かにあなたを助けることはできません.nsCenterOrOfficez

いずれにせよ、これは賢明な方法ではありません。通常、外部変数ではなく、viewForAnnotationのプロパティのみに依存する必要があります。annotation

于 2013-07-30T13:09:00.720 に答える