2012-12-04 38 views
3

我已根據座標創建了MKMapViewMKPolygon s。地圖上有多個多邊形(請參閱here,以瞭解我作爲應用程序重新創建的示例)。MKPolygon ontouch detailview

我想要做的是當用戶觸摸多邊形時,它會打開一個彈出窗口視圖並顯示有關位置的信息。這些信息當前存儲在一個plist文件中,並帶有座標。

到目前爲止,我目前得到的是,我能夠獲得觸摸事件並打印到多邊形被觸摸的日誌。

,我有這樣的問題:
可以MKPolygonView將其用作MKAnnotationView,即一旦用戶點擊針的詳細信息彈出關於當前位置?

我想爲多邊形視圖做同樣的事情。觸摸後,用戶可以看到有關儲存在plist中的位置的更多信息。如果可能的話,最好的辦法是什麼?

我目前的代碼如下。

#import "outagemapViewController.h" 
#import "MyAnnotation.h" 
#import "WildcardGestureRecognizer.h" 
#define METERS_PER_MILE 46309.344 
@interface outagemapViewController() 

@end 

@implementation outagemapViewController 
- (void)viewDidLoad { 

outages = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"outages"ofType:@"plist"]]; 


for (NSDictionary *coloredAreas in outages) { 
    coordinateData = coloredAreas[@"coords"]; 
test = coloredAreas[@"outages"]; 

    NSLog(@"test %@", test); 
    coordsLen = [coordinateData count]; 
     NSLog(@"coords %d", coordsLen); 
    CLLocationCoordinate2D coords[coordsLen]; 
    for (i=0; i < coordsLen; i++) { 
     NSString *lat = coordinateData[i]; 
     NSArray *latt = [lat componentsSeparatedByString:@","]; 
     double latitude = [[latt objectAtIndex:0] doubleValue]; 
     double longitude = [[latt objectAtIndex:1] doubleValue]; 
     coords[i] = CLLocationCoordinate2DMake(latitude, longitude); 

    } 


MKPolygon* poly2 = [MKPolygon polygonWithCoordinates:coords count:coordsLen]; 
[email protected]"test"; 
[self.mapView addOverlay:poly2]; 
} 
} 
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay { 
{ 
    if ([overlay isKindOfClass:[MKPolygon class]]) 
    { 

     MKPolygonView* aView = [[MKPolygonView alloc] initWithPolygon:(MKPolygon*)overlay]; 

     int numbers = [test intValue]; 

     if(numbers >= 10){ 
      aView.fillColor = [[UIColor greenColor] colorWithAlphaComponent:0.6]; 
      aView.strokeColor = [[UIColor greenColor] colorWithAlphaComponent:1.0]; 
      aView.lineWidth = 3; 
     }else if(numbers < 10){ 
      aView.fillColor = [[UIColor yellowColor] colorWithAlphaComponent:0.6]; 
      aView.strokeColor = [[UIColor yellowColor] colorWithAlphaComponent:1.0]; 
      aView.lineWidth = 3; 

        } 

     return aView; 
    } 


    return nil; 
} 
} 

-(void)viewWillAppear:(BOOL)animated{ 
CLLocationCoordinate2D zoomLocation; 
zoomLocation.latitude = 35.20418; 
zoomLocation.longitude = -89.86862; 

MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation,   0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE); 

[_mapView setRegion:viewRegion animated:YES]; 

WildcardGestureRecognizer * tapInterceptor = [[WildcardGestureRecognizer alloc] init]; 
tapInterceptor.touchesBeganCallback = ^(NSSet * touches, UIEvent * event) { 
    UITouch *touch = [touches anyObject]; 
    CGPoint point = [touch locationInView:self.mapView]; 

    CLLocationCoordinate2D coord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView]; 
    MKMapPoint mapPoint = MKMapPointForCoordinate(coord); 
    for (id overlay in self.mapView.overlays) 
    { 
     if ([overlay isKindOfClass:[MKPolygon class]]) 
     { 
      MKPolygon *poly = (MKPolygon*) overlay; 
      id view = [self.mapView viewForOverlay:poly]; 
      if ([view isKindOfClass:[MKPolygonView class]]) 
      { 
       MKPolygonView *polyView = (MKPolygonView*) view; 
       CGPoint polygonViewPoint = [polyView pointForMapPoint:mapPoint]; 
       BOOL mapCoordinateIsInPolygon = CGPathContainsPoint(polyView.path, NULL, polygonViewPoint, NO); 
       if (mapCoordinateIsInPolygon) { 
        // debug(@"hit!"); 
        NSLog(@"hit"); 
       } else { 
        NSLog(@"miss"); 
       } 
      } 
     } 
    } 

}; 
[self.mapView addGestureRecognizer:tapInterceptor]; 
} 

- (void)didReceiveMemoryWarning 
{ 
[super didReceiveMemoryWarning]; 
// Dispose of any resources that can be recreated. 
} 

@end 
+1

有什麼具體問題?命中檢測是否工作? – Anna

+2

沒有像註釋一樣的內置標註視圖。你將不得不創建一個自定義的UIView,並做addSubview或一個自定義的UIViewController並呈現/推送它。 – Anna

+0

啊。非常感謝你。我昨天非常沮喪,我想我忘了問真正的問題。儘管它已關閉,但仍爲您+1。 – Dwill

回答

3

不幸的是,對於覆蓋圖,沒有像註釋那樣的內置觸摸檢測和標註視圖。

您必須手動進行觸摸檢測,就像您已經在做的那樣(它看起來應該可以工作)。
(更加不幸的是,將手勢識別器直接添加到疊加視圖不起作用 - 您必須將其添加到整個地圖,然後檢查觸點是否在任何疊加層中。)

對於重疊標註視圖,一旦檢測到覆蓋圖上的觸摸,您可以創建自定義UIView並執行addSubview。我建議將其添加到地圖而不是覆蓋視圖,並且您可能可以使用您已計算的CGPoint point來確定自定義標註視圖的框架。

您可能還想保留對覆蓋圖標註視圖的ivar /屬性引用,以便在用戶點擊另一個覆蓋圖時又可以輕鬆移除和重新添加覆蓋圖,而另一個覆蓋圖的標註已顯示。

這可能是更容易的另一種選擇是創建一個自定義UIViewController和現在或推。顯示它的具體細節取決於您是否使用導航控制器和/或故事板。

如果您的應用程序也是爲iPad構建的,您還可以使用UIPopoverController顯示「標註」。
的代碼示例(這是與註釋,但你應該能夠適應它的覆蓋)查看How do I display a UIPopoverView as a annotation to the map view? (iPad)


一旦確定了哪個疊加層被點擊,您需要顯示其原始數據源( outages陣列)中的相關數據。眼下,創建覆蓋和添加,但有(在 outages陣列停運字典)沒有引用回到原來的數據對象。

(子類MKPolygon添加自定義屬性has issues and workarounds和創建一個完全自定義MKOverlay課程介紹了很多其他的額外工作。)

對於當前的數據源的結構,簡單,快速的(和有些粗糙)選項將疊加層的title屬性設置爲與疊加層關聯的中斷對象的outages陣列中的索引。就像你使用test

NSUInteger outageIndex = [outages indexOfObject:coloredAreas]; 
poly2.title = [NSString stringWithFormat:@"%d", outageIndex]; 
[self.mapView addOverlay:poly2]; 

viewForOverlay,它看起來(它來自一箇中斷對象):由於title屬性爲NSString和數組的索引是一個整數,我們將它轉​​換爲字符串確定多邊形的顏色。外部聲明/設置的test變量的值不一定與overlay同步,目前正在調用代理方法(地圖可能會多次調用viewForOverlay,但不一定按您添加的順序)。您必須根據overlay參數的某些屬性檢索停電對象。由於我們覆蓋的title屬性設置爲停運的指數:

//int numbers = [test intValue]; <-- remove this line 

int outageIndex = [overlay.title intValue]; 
NSDictionary *outageDict = [outages objectAtIndex:outageIndex]; 
id outageNumbersObject = outageDict[@"outages"]; 
//replace id above with actual type 
//can't tell from code in question whether it's NSString or NSNumber 
int numbers = [outageNumbersObject intValue]; 

//use "numbers" to set polygon color... 

最後,當覆蓋被竊聽,你用同樣的方法在viewForOverlay獲得停運對象:

if (mapCoordinateIsInPolygon) { 
    int outageIndex = [overlay.title intValue]; 
    NSDictionary *outageDict = [outages objectAtIndex:outageIndex]; 
    NSLog(@"hit, outageDict = %@", outageDict); 
    //show view with info from outageDict... 
} 
+0

嗨,安娜,你能給我一個例子,說明如何實現視圖和子視圖的上述代碼。我試圖NSLog從字典輸出,但它只顯示最後一個記錄。 – Dwill

+0

你試過的確切NSLog是什麼?也許你的問題是,你無法確定哪個中斷是覆蓋層?在停機數組中,每個對象都有一些與之相關的唯一字符串ID嗎?您可以將疊加層的「title」設置爲該唯一字符串,然後找到與該id相關聯的中斷對象。 – Anna

+0

是的,這是我遇到的問題。我有一個與每個中斷相關的中斷號碼,但我無法告訴哪些中斷已被中斷。你能舉出我應該做什麼的例子。 – Dwill