gpt4 book ai didi

iphone - MKPolygon 触摸细节 View

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:06:01 26 4
gpt4 key购买 nike

我已经创建了一个 MKMapView,其中包含基于坐标的 MKPolygon。 map 上有多个多边形(查看 here 以了解我重新创建为应用程序的示例)。

我想要做的是,当用户触摸多边形时,它会打开一个包含位置信息的弹出 View 。此信息当前存储在带有坐标的 plist 文件中。

我目前所拥有的是我能够获取触摸事件并打印到多边形被触摸的日志。

我的问题是:
MKPolygonView 能否像 MKAnnotationView 一样使用,一旦用户点击图钉,就会弹出有关当前位置的更多信息?

我想对多边形 View 执行相同的操作。触摸时,用户会看到有关存储在 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

最佳答案

不幸的是,对于叠加层,没有像注释那样的内置触摸检测和标注 View 。

您必须像您已经在做的那样手动进行触摸检测(看起来应该可以)。
(这里更不幸的是,将手势识别器直接添加到叠加 View 是行不通的——您必须将其添加到整个 map ,然后检查触摸点是否在任何叠加层中。)

对于覆盖标注 View ,一旦检测到覆盖上的触摸,您可以创建自定义 UIView 并执行 addSubview。我建议将它添加到 map 而不是叠加 View ,并且您可以使用您已经在计算的 CGPoint 点 来确定自定义标注 View 的框架。

您可能还希望保留对叠加层标注 View 的 ivar/属性引用,以便在用户点击另一个叠加层时可以轻松删除和重新添加它,而另一个叠加层的标注已经显示。

另一个可能更容易的选择是创建自定义 UIViewController 并呈现或推送它。显示它的细节取决于您是否使用导航 Controller 和/或 Storyboard。

如果您的应用也是为 iPad 构建的,您还可以使用 UIPopoverController 显示“callout”。
参见 How do I display a UIPopoverView as a annotation to the map view? (iPad)有关代码示例(它带有注释,但您应该能够针对叠加层调整它)。


一旦确定了哪个叠加层被点击,您需要显示原始数据源( outages 数组)中的相关数据。现在,创建并添加了叠加层,但没有对原始数据对象的引用( outages 数组中的中断字典)。

(子类化 MKPolygon 以添加自定义属性 has issues and workarounds 并创建一个完全自定义的 MKOverlay 类引入了许多其他额外的工作。)

对于您当前的数据源结构,一个简单、快速(但有些粗糙)的选项是将叠加层的 title 属性设置为 outages 数组中的索引与覆盖关联的中断对象。由于 title 属性是一个 NSString 并且数组索引是一个整数,我们将把它转换成一个字符串:

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

viewForOverlay 中,您似乎正在使用 test(来自中断对象)来确定多边形的颜色。外部声明/设置的 test 变量的值不一定与当前调用委托(delegate)方法的 overlay 同步( map 可以调用 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...
}

关于iphone - MKPolygon 触摸细节 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13708059/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com