我创建了一个基于坐标的带有MKMapView的MKPolygon。地图上有多个多边形(请看这里,看看我正在重新创建的应用程序)。
我想做的是,当用户触摸多边形时,它会打开一个弹出视图,其中包含有关位置的信息。此信息目前存储在具有坐标的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];
poly2.title=@"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发布于 2012-12-05 16:04:01
不幸的是,对于覆盖,没有内置的触摸检测和标注视图,就像注释一样。
您必须手动进行触摸检测,就像您已经在做的那样(看起来应该有效)。
(更不幸的是,将手势识别器直接添加到覆盖视图中是行不通的--您必须将其添加到整个地图中,然后检查触点是否在任何覆盖中。)
对于覆盖标注视图,一旦检测到对覆盖的触摸,就可以创建自定义UIView并执行addSubview。我建议将它添加到地图中而不是覆盖视图中,您可能可以使用已经计算好的CGPoint point来确定自定义标注视图的框架。
您还可能希望保留对覆盖标注视图的ivar/property引用,这样,如果用户点击另一个覆盖,则可以轻松地删除和重新添加它,而其他覆盖的标注已经显示。
另一个可能更容易的选择是创建一个自定义UIViewController并呈现或推送它。显示它的细节取决于您是否使用导航控制器和/或故事板。
如果您的应用程序也是为iPad构建的,您也可以使用UIPopoverController显示“标注”。
请参阅如何将UIPopoverView作为地图视图的注释显示?(iPad)中的代码示例(它带有注释,但您应该能够对其进行调整以适应覆盖)。
一旦确定了哪个覆盖被点击,就需要显示原始数据源( outages数组)中的关联数据。现在,创建并添加了覆盖,但没有引用原始数据对象( outages数组中的中断字典)。
(子类MKPolygon以添加自定义属性有问题和解决办法和创建一个完全自定义的MKOverlay类将引入许多其他额外工作。)
对于当前的数据源结构,一个简单、快速(而且有点粗糙)的选项是将overlay的title属性设置为与覆盖关联的中断对象的outages数组中的索引。由于title属性是一个NSString,而数组索引是一个整数,所以我们将它转换为一个字符串:
NSUInteger outageIndex = [outages indexOfObject:coloredAreas];
poly2.title = [NSString stringWithFormat:@"%d", outageIndex];
[self.mapView addOverlay:poly2];在viewForOverlay中,您似乎使用test (来自中断对象)来确定多边形的颜色。外部声明/设置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...
} https://stackoverflow.com/questions/13708059
复制相似问题