在显示标注之前先将MKMapView置于中心 [英] Center MKMapView BEFORE displaying callout

查看:101
本文介绍了在显示标注之前先将MKMapView置于中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

选择注释后,我试图居中放置MKMapView.我还启用了canShowCallout,但似乎iOS首先显示标注(当它不适合屏幕时会移动),然后移动地图,导致标注在屏幕上不完全可见.

I am trying to center an MKMapView after an annotation was selected. I also have enabled canShowCallout but it seems that iOS is first displaying the callout (which is shifted when it would not fit in the screen) and then the map is being moved, resulting in the callout being not completely visible on the screen.

在呈现和显示标注的位置之前,如何在地图上居中?

How can I center the map BEFORE the callout's position is being rendered and displayed?

推荐答案

我想完成同样的事情,最终完成了以下工作.

I wanted to accomplish the same thing and ended up doing the following.

在开始之前请注意:我知道解决方案非常丑陋!...但是,它有效.

A word of caution before I begin: I know the solution is pretty ugly!...but hey, it works.

注意:我的目标是iOS 9,但它应该可以在iOS的早期版本上运行:

Note: I am targeting iOS 9 but it should work on prior versions of iOS:

好的,我们开始:

  • 首先,在您的视图控制器中创建一个新属性,例如:@property(nonatomic, assign, getter=isPinCenteringOngoing) BOOL pinCenteringOngoing;
  • mapView:viewForAnnotation:中的
  • 为您的注释视图将canShowCallout设置为NO
  • 中的
  • 执行以下操作:

  • first off, create a new property in your view controller, e.g.: @property(nonatomic, assign, getter=isPinCenteringOngoing) BOOL pinCenteringOngoing;
  • in mapView:viewForAnnotation: set canShowCallout to NO for your annotationViews
  • in mapView:didSelectAnnotationView: do the following:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    if([view isKindOfClass:$YOURANNOTATIONVIEWCLASS$.class])
    {
        if(!self.isPinCenteringOngoing)
        {
            self.pinCenteringOngoing = YES;
            [self centerMapOnSelectedAnnotationView:($YOURANNOTATIONVIEWCLASS$ *)view];
        }
        else
        {
            self.pinCenteringOngoing = NO;
        }
    }
}

中的

  • 执行以下操作:

  • in mapView:didDeselectAnnotationView: do the following:

    - (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
    {
        if([view isKindOfClass:$YOURANNOTATIONVIEWCLASS$.class])
        {
            if(!self.isPinCenteringOngoing)
            {
                view.canShowCallout = NO;
            }
        }
    }
    

  • 并最终创建一个完成实际工作的新方法:

  • and finally create a new method that does the actual work:

    - (void)centerMapOnSelectedAnnotationView:($YOURANNOTATIONVIEWCLASS$ *)view
    {
        // Center map
        CGPoint annotationCenter = CGPointMake(CGRectGetMidX(view.frame), CGRectGetMidY(view.frame));
        CLLocationCoordinate2D newCenter = [self.mapView convertPoint:annotationCenter toCoordinateFromView:view.superview];
        [self.mapView setCenterCoordinate:newCenter animated:YES];
    
        // Allow callout to be shown
        view.canShowCallout = YES;
    
        // Deselect and then select the annotation so the callout is actually displayed
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void)
        {
            [self.mapView deselectAnnotation:view.annotation animated:NO];
    
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void)
            {
                [self.mapView selectAnnotation:view.annotation animated:NO];
            });
        });
    }
    

  • 为完成我的回答,以下是关于我在上面的代码中所做的事情以及为什么这样做的文字说明:

    To complete my answer, here is a textual explanation of what I'm doing in the code above and why I'm doing it:

    • 我想要的是将注释放置在屏幕上居中,并将标注放置在屏幕上方.
    • 默认情况下,我得到的是:
      • 选择注释时,地图将打开标注,并在必要时调整地图以使标注适合屏幕显示.这种标准实现绝不能保证标注在注释上方居中".
      • 通过使用setCenterCoordinate:将地图居中,注释视图将在地图上居中.
      • 现在,由于注释在地图上居中,因此前面两个点的组合可能导致标注被切除".
      • What I want is the annotation to be centered on screen, and the callout to be centered above it.
      • What I get by default is:
        • When selecting an annotation, the map opens the callout, and if necessary adjusts the map so the callout fits on screen. By no mean does that standard implementation guarantee, that the callout is "centered" above the annotation.
        • By centering the map with setCenterCoordinate:, the annotation view is centered on the map.
        • Now the two previous points combined can result in the callout to be "cut off" as the annotation is centered on the map, but the callout is not centered above the annotation.
        • 首先我禁用默认显示的标注,将每个annotationView的canShowCallout设置为NO
        • 当用户选择注释时,我首先将地图居中
        • 然后我允许显示标注,将所选注释的canShowCallout设置为YES
        • 然后我取消选择,然后再次选择注释,这样标注实际上就显示了
        • 为了使标注正确地位于注释上方,我需要进行一些延迟的取消选择/选择,以便地图居中可以完成

        我希望我的回答可能会有用.

        I hope my answer may prove useful.

        这篇关于在显示标注之前先将MKMapView置于中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆