2014-04-23 62 views
1

這個問題已經讓我煩惱幾個星期了!顯示自定義多個針腳顯示針對位置的針腳錯誤

我有一個標籤欄應用程序。在一個標籤上輸入點數,在另一個標籤上,點數顯示在地圖上。針腳應該不同,取決於點的類型。

我面對的問題是,每當我從一個標籤切換到另一個標籤時,針腳圖像會從應該變成其他圖像。例如,如果我在地圖上有四個點,三個顯示爲一個圓形,另一個顯示爲三角形,則三角形將從一個點移動到另一個點。圖像似乎隨機改變。

所以,這是代碼:

ViewController.m

-(void) viewWillAppear:(BOOL)animated 
{ 
    // Select the type of map 
    if (isMapSelected == NO) { 
     self.mapView.mapType = MKMapTypeSatellite; 
    } 

    else { 
     self.mapView.mapType = MKMapTypeStandard; 
    } 


    // Add region to the map (center and span) 
    [self addRegion]; 

    // Removing old annotation 
    [self.mapView removeAnnotations:mapLocations]; 

    // Initializing arrays for the annotations 
    mapLocations = [[NSMutableArray alloc]init]; 

    [self addAnnotation]; 
} 


-(void) addAnnotation 
{ 

    CLLocationCoordinate2D mapLocation; 
    IGAMapAnnotation *mapAnnotation; 

    // Calculate how many points are included 
    NSInteger numberOfPoints = [coordinatesTempArray count]; 

    // Annotations will be added only of the flight plan includes at least one point 
    if (numberOfPoints > 0) 
    { 
    // Trying to add coordinates from the array of coordinates 
    for (NSInteger i=0; i < ([coordinatesTempArray count]); i++) { 

     mapAnnotation = [[IGAMapAnnotation alloc]init]; 

     // Taking a point in the array and getting its coordinates 
     self.mapCoordinates = [coordinatesTempArray objectAtIndex:i]; 

     // Getting a point in the array and getting its lattitude and longitude 
     self.mapLatitude = [[self.mapCoordinates objectAtIndex:0]doubleValue]; 
     self.mapLongitude = [[self.mapCoordinates objectAtIndex:1]doubleValue]; 

     // Assigning the point coordinates to the coordinates to be displayed on the map 
     mapLocation.latitude = self.mapLatitude; 
     mapLocation.longitude = self.mapLongitude; 

     // Adding coordinates and title to the map annotation 
     mapAnnotation.coordinate = mapLocation; 
     mapAnnotation.title = [navaidNamesTempArray objectAtIndex:i]; 
     mapAnnotation.subtitle = nil; 
     mapAnnotation.navaidType = [navaidTypesTempArray objectAtIndex:i]; 

     // Adding the annotation to the array that will be added to the map 
     [mapLocations addObject:mapAnnotation]; 
    } 

    // Adding annotations to the map 
    [self.mapView addAnnotations:mapLocations]; 
    } 
} 


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

    if([annotation isKindOfClass:[IGAMapAnnotation class]]) 
    { 
    IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation; 
    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"IGAMapAnnotation"]; 

    if (annotationView == nil) 
     annotationView = myLocation.annotationView; 
    else 
     annotationView.annotation = annotation; 
    return annotationView; 
    } 
    else 
     return nil; 
} 

IGAMapAnnotation.m

@synthesize coordinate = _coordinate; 
@synthesize title = _title; 
@synthesize subtitle = _subtitle; 
@synthesize type = _type; 

// Tried to have this init method but was never able to make it work. Without it, the program crashes too!!!! 

-(id)initWithTitle:(NSString *)newTitle Type:(NSString *)type Location:(CLLocationCoordinate2D) newCoordinate 
{ 
    self = [super init]; 

    if (self) { 
     _title = newTitle; 
     _coordinate = newCoordinate; 
     _type = type; 
    } 

    return self; 
} 


-(MKAnnotationView *) annotationView { 
    MKAnnotationView *annotationView = [[MKAnnotationView alloc]initWithAnnotation:self reuseIdentifier:@"IGAMapAnnotation"]; 
    annotationView.enabled = YES; 
    annotationView.canShowCallout = YES; 
    annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 

    if ([self.type isEqual: @"A"] || [self.type isEqual: @"B"] || [self.type isEqual: @"C"]) 
    { 
    annotationView.image = [UIImage imageNamed:@"circle.png"]; 
    } 
    else if ([self.type isEqual: @"D"]) 
    { 
    annotationView.image = [UIImage imageNamed:@"triangle.png"]; 
    } 
    else if ([self.type isEqual: @"E"]) 
    { 
    annotationView.image = [UIImage imageNamed:@"square.png"]; 
    } 
    else 
    { 
    annotationView.image = [UIImage imageNamed:@"oval.png"]; 
    } 
    return annotationView; 
} 

@end 

這是它。到目前爲止,這種行爲對我來說毫無意義。 感謝您的幫助!

+0

一個注意:此移動'[self.mapView removeAnnotations:mapLocations]'從viewWillAppear中到addAnnotation解決了上述問題,但是,則舊註釋銷不會被刪除。 –

回答

3

這聽起來像一個註解視圖重用問題。

當註釋重新顯示時,它們將重複使用含有先前註釋圖像的視圖。視圖中的image屬性未被更新,因爲它應該被重新用於其他註釋。

viewForAnnotation委託方法,此代碼看上去錯誤的:

MKAnnotationView *annotationView = [mapView dequeue... 
if (annotationView == nil) 
    annotationView = myLocation.annotationView; 
else 
    annotationView.annotation = annotation; 

如果dequeue返回一個視圖(即,其可以爲一個不同類型的註釋被創建先前創建的圖。 ),其annotation屬性已更新,但其image屬性未更新。

現有代碼只創建一個新的註釋視圖(當dequeue返回nil)當設置image屬性。

眼下,註釋視圖創建和image -setting代碼是在註釋模型IGAMapAnnotation。最好創建一個自定義MKAnnotationView類,該類自動更新image屬性,只要它的annotation屬性更新。

但是,另一種替代方法是將所有邏輯放在viewForAnnotation委託方法本身中(並從IGAMapAnnotation類中除去annotationView方法)。更新viewForAnnotation委託方法的

實施例:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation 
{ 
    if (! [annotation isKindOfClass:[IGAMapAnnotation class]]) 
    { 
     //return default view if annotation is NOT of type IGAMapAnnotation... 
     return nil; 
    } 


    MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"IGAMapAnnotation"]; 

    if (annotationView == nil) 
    { 
     annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"IGAMapAnnotation"]; 
     //these properties don't change per annotation 
     //so they can be set only when creating a new view... 
     annotationView.enabled = YES; 
     annotationView.canShowCallout = YES; 
     annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
    } 
    else 
    { 
     annotationView.annotation = annotation; 
    } 


    //whether we are using a completely new view or a re-used view, 
    //set the view's image based on the current annotation... 

    IGAMapAnnotation *myLocation = (IGAMapAnnotation *) annotation; 
    if ([myLocation.type isEqual: @"A"] || [myLocation.type isEqual: @"B"] || [myLocation.type isEqual: @"C"]) 
    { 
     annotationView.image = [UIImage imageNamed:@"circle.png"]; 
    } 
    else if ([myLocation.type isEqual: @"D"]) 
    { 
     annotationView.image = [UIImage imageNamed:@"triangle.png"]; 
    } 
    else if ([myLocation.type isEqual: @"E"]) 
    { 
     annotationView.image = [UIImage imageNamed:@"square.png"]; 
    } 
    else 
    { 
     annotationView.image = [UIImage imageNamed:@"oval.png"]; 
    } 


    return annotationView; 
} 
+0

安娜。我用你的替代方法,看起來像是正常工作。非常感謝!!! –