在JSON解析之后-viewForAnnotation在MKMapView上只显示一个单独的注释

时间:2013-02-05 12:01:32

标签: ios objective-c mkmapview afnetworking mkannotationview

我需要在我的MkMapView上显示大约10个位置(和相应的注释),按下按钮后我需要根据不同的JSON解析结果添加新的不同注释(例如,locationIDValue< 100表示​​红色引脚,否则绿色)。这是简化的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];
    map.showsUserLocation = true;
    map.mapType = MKMapTypeStandard;

    arrayID = [[NSMutableArray alloc] initWithObjects: @"id1", @"id2", @"id3", @"id4", @"id5", @"id6", @"id7", @"id8", @"id9", @"id10", nil]; 

    #define MakeLocation(lat,lon) [[CLLocation alloc] initWithLatitude:lat longitude:lon]

    locations= @[ MakeLocation(lat1,lon1), MakeLocation(lat2,lon2), MakeLocation(lat3,lon3), MakeLocation(lat4,lon4), MakeLocation(lat5,lon5), MakeLocation(lat6,lon6), MakeLocation(lat7,lon7), MakeLocation(lat8,lon8), MakeLocation(lat9,lon9), MakeLocation(lat10,lon10) ];

    for (int l=0; l<[locations count]; l++) { // HERE ITS PERFECT! I CAN SEE ALL 10 ANNOTATIONS!
        MKPointAnnotation* annotation= [MKPointAnnotation new];
        annotation.coordinate = [locations[l] coordinate];
        [map addAnnotation: annotation];
    }
}

   - (IBAction)parseMethod {

        [map removeAnnotations:map.annotations];

        for (int i=0; i < [arrayID count]; i++) { // arrayID contains ID values to parse for each location

            NSURL *url = [NSURL URLWithString:
                          [NSString stringWithFormat:
                           @"http://JSONPARSINGURL/%@",[arrayID objectAtIndex:i]]];

            NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:5.0];
            operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

        // PARSING CODE . . .

                NSMutableArray *value = [JSON objectForKey:@"value"];
                NSMutableDictionary *value0 = [value objectAtIndex:0];
                [valueID replaceObjectAtIndex:i withObject:[value0 objectForKey:@"valueID"]];
                locationIDValue = [[valueID objectAtIndex:i] intValue]; // locationIDValue contains the values that i must use to put different annotations on the map

                NSLog(@"locationIDValue: %d", locationIDValue); // here I control IF app parses all the values of locationIDValue

                [table reloadData]; // here I put another control to see all values parsed

            }
                                                                        failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
                                                                            NSLog(@"FAILURE");
                                                                        }];

            NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // I have used also simple [operation start] but I have same issue!
            [queue addOperation:operation];
            [queue waitUntilAllOperationsAreFinished];

    }

        NSLog(@"END PARSING"); // here I control the end of parsing, so now I can add new annotations to MKMapView according to locationIDValue array

        MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
        for (int l=0; l<[locations count]; l++) { // HERE I CAN SEE ONLY A SINGLE LOCATION!
            annotation.coordinate = [locations[l] coordinate];

            NSLog(@"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude); // here I control IF app parses all the values of coordinates

            [map addAnnotation: annotation];
        }

    }

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

    MKPinAnnotationView *pinView=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"];
    pinView.animatesDrop=YES;

    if (annotation != map.userLocation)
    {
        if ( locationIDValue <= 100) {
            pinView.pinColor = MKPinAnnotationColorRed;
            return pinView;
        }
        pinView.pinColor = MKPinAnnotationColorGreen;
        return pinView;
    }
    else
    map.userLocation.title = @"My position";
    return nil;
}

情况: 当我第一次打开app时,根据#define MakeLocation纬度和经度,我可以在地图上看到所有注释。但是如果我按下按钮并启动parseMethod,我会等待几秒钟(根据NSOperationQueue,但我也可以在没有队列的情况下测试它,只需要简单的[操作开始]代码),然后我就可以看到地图上只有一个单一的注释,总是一样的,奇怪的是在第五个位置,使用lat5-lon5坐标(否则,如果我更改了一些代码,我可以看到所有的注释都落在相同的位置)。你可以看到我写了一些NSLog代码并添加UITableView来控制活动,这就是结果:

END PARSING
coordinates: lat1 - lon1
coordinates: lat2 - lon2
coordinates: lat3 - lon3
coordinates: lat4 - lon4
coordinates: lat5 - lon5   <--- THE STRANGE POSITION
coordinates: lat6 - lon6
coordinates: lat7 - lon7
coordinates: lat8 - lon8
coordinates: lat9 - lon9
coordinates: lat10 - lon10
locationIDValue: 100
locationIDValue: 90
locationIDValue: 50
locationIDValue: 120
locationIDValue: 20
locationIDValue: 40
locationIDValue: 80
locationIDValue: 180
locationIDValue: 140
locationIDValue: 10

好吧,它看起来很完美:app解析所有数据(也是UITableView用所有新值解析的行填充行),所以在解析操作结束后我认为我们有足够的值来用新注释填充地图。嗯,这里有什么问题?解析后为什么我只能看到一个注释?或者,所有注释都落在同一位置?请给我一个帮助!

2 个答案:

答案 0 :(得分:3)

parseMethod中,更改此内容:

MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
for (int l=0; l<[locations count]; l++) { // HERE I CAN SEE ONLY A SINGLE LOCATION!
    annotation.coordinate = [locations[l] coordinate];

    NSLog(@"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude); // here I control IF app parses all the values of coordinates

    [map addAnnotation: annotation];
}

到此:

for (int l=0; l<[locations count]; l++) { // HERE I CAN SEE ONLY A SINGLE LOCATION!

    //create a NEW annotation for each location...
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];

    annotation.coordinate = [locations[l] coordinate];

    NSLog(@"%f - %f", annotation.coordinate.latitude, annotation.coordinate.longitude); // here I control IF app parses all the values of coordinates

    [map addAnnotation: annotation];
}

MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]移动到里面的 for循环,以便为每个位置创建一个新的注释对象。

现有的代码创建了一个注释对象,并且只是不断修改它的坐标。

答案 1 :(得分:0)

What is also really important to note (because it was very hard to find that error and I sat the whole last night in front of this...) is to check if your object that conforms to MKAnnotation has some master base class that imlements the methods isEqual and / or hash on only the data of the base class and you do not overwrite that in your base class. This was my problem and thus isEqual returned YES for all annotations and THUS it showed always only one annotation on the map. I couldn't find any hint on the internet about this so I will leave at least this comment here for poor people in the same situation.