2012-03-02 79 views
6

我有一個帶有註釋的地圖視圖,這些註釋顯示一個標註。當標註的披露細節按鈕被點擊時,它會進入一個新的視圖。MKMapView註釋更改/丟失順序?

我的MKAnnotations是一個實現了<MKAnnotation>的自定義類。我們稱之爲類MyClass。它們存儲在一個NSMutableArray中。在此視圖的viewdidload期間,我將此數組中的MyClass的每個對象添加到地圖視圖的註釋中。使用調試器,我可以看到一旦完成所有這些添加,[self.MapView註釋]順序與NSMutableArray相同。

現在我在mapView:viewForAnnotation中設置另一個斷點:並檢查1)我的NSMutableArray和2)[self.MapView註釋]的順序。該數組當然是以相同的順序。但是,註釋的順序已經混亂。

這對我來說是個大問題,因爲我需要使用用戶在下一個視圖中選擇的MyClass的特定實例。 AKA,我想看看註釋,找到它的索引,然後用它來獲得數組中相同的索引。

我現在已經意識到,我可以直接保存註釋(來自Android背景,這對我來說非常酷)。然而,我仍然無法理解爲什麼訂單被炒得沸沸揚揚。有人能幫我嗎?下面的代碼:

- (void)viewDidLoad 
{ 


    if([fromString isEqualToString:@"FromList"]) 
     self.navigationItem.hidesBackButton = TRUE; 
    else { 
     self.navigationItem.rightBarButtonItem = nil; 
    } 


    self.array = [MySingleton getArray]; 
    //set up map 

    //declare latitude and longitude of map center 
    CLLocationCoordinate2D center; 
    center.latitude = 45; 
    center.longitude = 45; 

    //declare span of map (height and width in degrees) 
    MKCoordinateSpan span; 
    span.latitudeDelta = .4; 
    span.longitudeDelta = .4; 

    //add center and span to a region, 
    //adjust the region to fit in the mapview 
    //and assign to mapview region 
    MKCoordinateRegion region; 
    region.center = center; 
    region.span = span; 
    MapView.region = [MapView regionThatFits:region]; 

    for(MyClass *t in self.array){ 
     [MapView addAnnotation:t]; 
    } 
    [super viewDidLoad]; 
} 



//this is the required method implementation for MKMapView annotations 
- (MKAnnotationView *) mapView:(MKMapView *)thisMapView 
      viewForAnnotation:(MyClass *)annotation 
{ 


    static NSString *identifier = @"MyIdentifier"; 

    //the result of the call is being cast (MKPinAnnotationView *) to the correct 
    //view class or else the compiler complains 
    MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[thisMapView 
                    dequeueReusableAnnotationViewWithIdentifier:identifier]; 
    if(annotationView == nil) 
    { 
     annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; 
    } 

    annotationView.pinColor = MKPinAnnotationColorGreen; 

    //pin drops when it first appears 
    annotationView.animatesDrop=TRUE; 

    //tapping the pin produces a gray box which shows title and subtitle 
    annotationView.canShowCallout = YES; 

    UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
    annotationView.rightCalloutAccessoryView = infoButton; 


    return annotationView; 
} 

回答

6

當你調用addAnnotationaddAnnotations,地圖視圖添加引用(S)到其內部的註釋的列表。

MKMapViewannotations屬性簡單地返回這個內部列表(不管它可能是什麼類型)作爲NSArray

我不知道文檔中的任何地方,它指出annotations屬性按照您添加註釋的相同順序返回數組。如果您打開showsUserLocation,則數組將包含該註釋甚至儘管你沒有明確地添加它。

您不需要關心也不應該依賴annotations屬性中的對象順序。

  • 由於您array包含實現<MKAnnotation>,而不是通過它循環,可以一次性添加所有的標註對象通過調用addAnnotations(複數)和通:

    只是關於代碼的一些建議它是陣列

  • viewForAnnotation中,您設置的屬性都不依賴於任何特定的註釋,因此您可以將它們全部設置在if (av == nil)塊內。這樣你可以最大限度地重用。
  • 同樣在viewForAnnotation之後,在if之後,應該將視圖的annotation屬性設置爲當前註釋。這是爲了防止視圖從其他註釋中重用。
  • 最後,在viewForAnnotation中,不要假設annotation的類型爲MyClass。如果您打開showsUserLocation,情況就不會如此。將參數聲明爲id<MKAnnotation>比較安全,然後在必要時檢查它的類是什麼,然後施放它。
+0

謝謝您的最後一個點。始終學習 – 2012-12-04 23:29:44

1

@Anna,你說你不應該關注註釋的順序。我的情況並非如此。一些註釋視圖可能會重疊,我總是需要一個特定視圖來放置在兩個重疊視圖的頂部。因此,DO的順序對於註釋是有意義的,因爲我希望- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation按照與添加註釋相同的順序被調用。

編輯: and the solution is here :-)

+1

鏈接的解決方案是關於註釋** _ views _ **(而不是id ** _ model _ **對象,這是OP的問題所在)的顯示順序。另外,viewForAnnotation委託方法_can_可以被多次調用,即使添加了相同的註釋(例如,如果您滾動/縮放地圖並且註釋回到屏幕上)。您的假設可能會與少量註釋或特定操作系統版本「工作」,但您不應該希望或依賴它。 – Anna 2013-02-12 19:36:57

+0

那麼,Anna,註釋的z順序根本不可配置? – wreckgar23 2013-07-02 14:05:59