自定义在MKMapView上重新加载时要切换的注释

时间:2013-07-30 01:02:52

标签: objective-c annotations nsmutablearray mapkit

我这个问题已经持续了几个星期了,我还没有找到答案。在我的MapView上我有自定义注释,当我点击“重新加载按钮”时,所有信息都是正确的,如注释“标题,副标题”。但是注释已经改变了。注释在NSMutableArray中,我确信我所遇到的问题围绕着这个问题。这是我用来重新加载注释的代码。

所以只是防止任何混淆,我的自定义注释在我第一次加载mapView时工作得很好。但是一旦我点击重新加载按钮,所有注释的信息,如“位置,标题,副标题”都是正确的,只是实际的注释已经改变。就像所有的注释都被切换了一样。 如果有人可以提供帮助,我们将不胜感激!谢谢!

- (IBAction)refreshMap:(id)sender {
NSArray *annotationsOnMap = myMapView.annotations;
[myMapView removeAnnotations:annotationsOnMap];
[locations removeAllObjects];
[citiesArray removeAllObjects];
[self retrieveData];
}


-(void) retrieveData {
userLAT = [NSString stringWithFormat:@"%f", myMapView.userLocation.coordinate.latitude];
userLNG = [NSString stringWithFormat:@"%f", myMapView.userLocation.coordinate.longitude];

NSString *fullPath = [mainUrl stringByAppendingFormat:@"map_json.php?userID=%@&lat=%@&lng=%@",theUserID,userLAT,userLNG];

NSURL * url =[NSURL URLWithString:fullPath];
NSData *data = [NSData dataWithContentsOfURL:url];

json =[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];


citiesArray =[[NSMutableArray alloc]init];
for (int i = 0; i < json.count; i++)
{
    //create city object
    NSString * eID =[[json objectAtIndex:i] objectForKey:@"userid"];
    NSString * eAddress =[[json objectAtIndex:i] objectForKey:@"full_address"];
    NSString * eHost =[[json objectAtIndex:i] objectForKey:@"username"];
    NSString * eLat =[[json objectAtIndex:i] objectForKey:@"lat"];
    NSString * eLong =[[json objectAtIndex:i] objectForKey:@"lng"];
    NSString * eName =[[json objectAtIndex:i] objectForKey:@"Restaurant_name"];
    NSString * eState = [[json objectAtIndex:i] objectForKey:@"type"];
    NSString * annotationPic = [[json objectAtIndex:i] objectForKey:@"Annotation"];
    NSString * eventID = [[json objectAtIndex:i] objectForKey:@"id"];

    //convert lat and long from strings

    float floatLat = [eLat floatValue];
    float floatLONG = [eLong floatValue];
    City * myCity =[[City alloc] initWithRestaurantID: (NSString *) eID andRestaurantName: (NSString *) eName andRestaurantState: (NSString *) eState andRestaurantAddress: (NSString *) eAddress andRestaurantHost: eHost andRestaurantLat: (NSString *) eLat andRestaurantLong: (NSString *) eLong];
    //Add our city object to our cities array
    // Do any additional setup after loading the view.

    [citiesArray addObject:myCity];

    //Annotation

    locations =[[NSMutableArray alloc]init];
    CLLocationCoordinate2D location;
    Annotation * myAnn;

    //event1 annotation
    myAnn =[[Annotation alloc]init];
    location.latitude = floatLat;
    location.longitude = floatLONG;
    myAnn.coordinate = location;
    myAnn.title = eName;
    myAnn.subtitle = eHost;
    myAnn.type = eState;
    myAnn.AnnotationPicture = annotationPic;
    myAnn.passEventID = eventID;
    myAnn.hotZoneLevel = hotZone;
    [locations addObject:myAnn];
    [self.myMapView addAnnotations:locations];

}

}



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

if([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

static NSString *annotationIdentifier = @"AnnotationIdentifier";

MKAnnotationView *annotationView = (MKAnnotationView *) [self.myMapView
                                                         dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];

if (!annotationView)
{
    annotationView = [[MKAnnotationView alloc]
                      initWithAnnotation:annotation
                      reuseIdentifier:annotationIdentifier];

    NSString *restaurant_Icon = ((Annotation *)annotation).AnnotationPicture;
    NSString *restaurant_Callout = [NSString stringWithFormat:@"mini.%@",restaurant_Icon];

    UIImage *oldImage = [UIImage imageNamed:restaurant_Icon];
    UIImage *newImage;
    CGSize newSize = CGSizeMake(75, 75);

    newImage = [oldImage imageScaledToFitSize:newSize]; // uses MGImageResizeScale


    annotationView.image= newImage;

    annotationView.canShowCallout = YES;

    UIImage *Mini_oldImage = [UIImage imageNamed:event_Callout];
    UIImage *Mini_newImage;
    CGSize Mini_newSize = CGSizeMake(30,30);

    Mini_newImage = [Mini_oldImage imageScaledToFitSize:Mini_newSize]; // uses MGImageResizeScale

    UIImageView *finalMini_callOut = [[UIImageView alloc] initWithImage:Mini_newImage];
    annotationView.leftCalloutAccessoryView = finalMini_callOut;


    UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];


    annotationView.rightCalloutAccessoryView = rightButton;

}
else
{
    annotationView.annotation = annotation;
}

return annotationView;
}

1 个答案:

答案 0 :(得分:1)

如果不出意外,您将根据注释设置图标和标注,但仅在注释未出列时才在viewForAnnotation中执行此操作。如果重复使用注释视图,您确实希望在if块之外进行任何特定于注释的自定义。


与您报告的问题无关,还有一些其他观察结果:

  1. 您可能应该异步执行retrieveData,这样就不会将主线程与数据检索/解析捆绑在一起。继续向你的阵列发送添加条目并将注释添加到主队列中的地图,但网络内容应该是异步完成的。

  2. 您可能应检查以确保data不是nil(例如,没有网络连接或其他网络错误),因为如果您将JSONObjectWithData传递给nil将会崩溃{1}}值。

  3. 您对locations的使用似乎没有必要,因为您正在为JSON中的每个条目重置它。您可以(a)完全退出locations,只需将myAnn对象添加到地图的注释中;或(b)在locations循环之前初始化for。但是维护这个ivar可能会产生误导,但只能用最后一个注释填充它。