Ios 缩放到随机注释并在地图视图加载时显示气泡

Ios 缩放到随机注释并在地图视图加载时显示气泡,ios,mapkit,Ios,Mapkit,我试图缩放到一个随机注释,并让气泡自动打开 我将注释固定在viewDidLoad中,如下所示: ...arrays... for (int i=0; i<22; i++){ MKPointAnnotation *annot = [[MKPointAnnotation alloc] init]; annot.title = [wineryName objectAtIndex:i]; annot.subtitle = [wineryAddress object

我试图缩放到一个随机注释,并让气泡自动打开

我将注释固定在viewDidLoad中,如下所示:

...arrays...

    for (int i=0; i<22; i++){
    MKPointAnnotation *annot = [[MKPointAnnotation alloc] init];
    annot.title = [wineryName objectAtIndex:i];
    annot.subtitle = [wineryAddress objectAtIndex:i];
    annot.coordinate = CLLocationCoordinate2DMake([[lat objectAtIndex:i]doubleValue],             [[lon objectAtIndex:i]doubleValue]);
    [mapView setCenterCoordinate:annot.coordinate animated:YES];
    [mapView addAnnotation:annot];
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{


if ([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

//dequeue an existing pin view first
static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
                                 initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
pinView.pinColor=MKPinAnnotationColorRed;


UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 35, 35);
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
[button setImage:[UIImage imageNamed:@"RightArrow.png"] forState:UIControlStateNormal];
[button addTarget:self action:@selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
pinView.rightCalloutAccessoryView = button;

...arrays...

 for (int i = 0; i < 22; i++) {
        if ([wineryTitle[i] isEqualToString:[annotation title]]) {
            UIImageView *profileIconView = [[UIImageView alloc] init];
            profileIconView.frame = CGRectMake(0, 0, 40, 33);
            profileIconView.image = [UIImage imageNamed:wineryImage[i]];
            pinView.leftCalloutAccessoryView = profileIconView;
            [profileIconView release];
            break;


        }

}

return pinView;
- (void)zoomToUserLocation:(MKUserLocation *)userLocation
{
if (!userLocation)
    return;

MKCoordinateRegion region;

//zoom to random pin when page loads

int randomNumber = rand() % 22;
switch (randomNumber) {
    case 1:
        region.center = CLLocationCoordinate2DMake(34.642109, -120.440292);

        [self.mapView selectAnnotation:[self.mapView.annotations objectAtIndex:0] animated:TRUE];
        break;
    case 2:
        region.center = CLLocationCoordinate2DMake(34.667408, -120.334781);

        [self.mapView selectAnnotation:[self.mapView.annotations objectAtIndex:1] animated:TRUE];
        break;
    case 3:
    ...etc

}
region.span = MKCoordinateSpanMake(5.0, 5.0);
region = [self.mapView regionThatFits:region];
[self.mapView setRegion:region animated:YES];

}
除了:在zoomToUserLocation方法中,地图将缩放到一个位置,然后显示不同位置的气泡。看起来,随机操作符分别随机选择一个位置和一个气泡。是否有人知道如何修复此问题,以便气泡自动出现在随机选择的同一位置

zoomToUserLocation方法中的代码错误地假设地图视图的注释数组只包含显式添加的注释,更重要的是注释数组的顺序与添加注释的顺序相同

这两种假设都是不安全的。 有关更多讨论,请参阅

您的应用程序显然添加了22条注释,但:

如果showsUserLocation为“是”,则地图视图的注释数组将包含23个注释22以及地图自身添加的用户位置。 无法保证地图注释数组中索引N处的注释与winery数组中索引N处的注释相同。 为了简单地缩放到随机位置,实际上不需要在地图的注释数组和您自己的数组之间建立链接

相反,可以从注释数组本身随机选择的注释中检索要居中的坐标

例如:

MKCoordinateRegion region;

//make list of annotations excluding the user location
NSMutableArray *myAnnotations = [NSMutableArray arrayWithCapacity:10];
for (id<MKAnnotation> ann in self.mapView.annotations)
{
    if (! ([ann isKindOfClass:[MKUserLocation class]]))
        [myAnnotations addObject:ann];
}

int numOfAnnotations = myAnnotations.count;

//if no annotations to choose from, do nothing
if (numOfAnnotations == 0)
    return;

int randomNumber = rand() % numOfAnnotations;
//suggest using arc4random instead of rand
//see https://stackoverflow.com/questions/160890/generating-random-numbers-in-objective-c

id<MKAnnotation> randomAnnotation = [myAnnotations objectAtIndex:randomNumber];

region.center = randomAnnotation.coordinate;

[self.mapView selectAnnotation:randomAnnotation animated:YES];

region.span = ... //rest of the code as-is
//however, calling regionThatFits is unnecessary
还有许多其他不相关的改进可以对代码进行,但这些必须是单独的问题的主题。然而,这里有几个

我可以建议的一个主要改进是创建一个名为Winery的自定义注释类,它可以将Winery的所有数据合并到一个对象中,而不是对名称、地址、纬度、经度、图像等使用单独的数组

这将使开发和未来的更改更易于管理

第二个主要改进是删除viewForAnnotation委托方法中的低效循环,该方法搜索酒厂名称以设置左侧附件视图的图像。每次需要注释视图时都会执行此搜索循环。只有22个注释,您可能不会注意到性能问题,但这是不必要的工作。如果完成了第一项改进,则可以消除搜索循环,因为注释的所有属性都已在注释对象中


有关上述内容,请参见。

你好,安娜。这很有效。这正是我想要做的,尽管我自己永远也不会明白!!只是比我现在的Oc水平稍微高一点。我对用于整合阵列的自定义类感兴趣,这是我有点陌生的另一个领域。在标注中添加图像的循环是目前我能找到的最好的解决方案,但实际上我已经创建了两次wineries数组,我知道这不是一个好主意。我会检查你的链接,但如果你有任何片段,这将是伟大的。我不确定人们是否会进入私人模式进行讨论,所以。。。