【问题标题】:How to add annotation on center of map view in iPhone?如何在 iPhone 的地图视图中心添加注释?
【发布时间】:2011-06-28 09:43:59
【问题描述】:

我的应用中有 MAP 视图,我想在地图视图的中心添加注释图钉(红色图钉)。
现在,当用户滚动地图视图时,应根据该图调整中心。
如何做到这一点?
谢谢

【问题讨论】:

  • 表示你正在通过改变中心来改变pin的位置。
  • @Muhammad Zeeshan - 是的,当用户滚动地图时,红色的大头针(注释)应该改变以适应用户可见的新地图视图中心。
  • 试着把注解放到地图的中心
  • 我认为您应该尝试将 pin 添加为 mapView 中心的子视图。
  • 是的,但是我如何获得地图的坐标?

标签: iphone annotations mkmapview center


【解决方案1】:

如果您想使用实际注释而不是仅使用位于地图视图中心上方的常规视图,您可以:

  • 使用具有可设置坐标属性的注释类(例如预定义的MKPointAnnotation 类)。这样可以避免在中心更改时必须删除和添加注释。
  • 在 viewDidLoad 中创建注解
  • 在属性中保留对它的引用,例如 centerAnnotation
  • 在地图视图的 regionDidChangeAnimated 委托方法中更新其坐标(和标题等)(确保已设置地图视图的委托属性)

例子:

@interface SomeViewController : UIViewController <MKMapViewDelegate> {
    MKPointAnnotation *centerAnnotation;
}
@property (nonatomic, retain) MKPointAnnotation *centerAnnotation;
@end

@implementation SomeViewController

@synthesize centerAnnotation;

- (void)viewDidLoad {
    [super viewDidLoad];

    MKPointAnnotation *pa = [[MKPointAnnotation alloc] init];
    pa.coordinate = mapView.centerCoordinate;
    pa.title = @"Map Center";
    pa.subtitle = [NSString stringWithFormat:@"%f, %f", pa.coordinate.latitude, pa.coordinate.longitude];
    [mapView addAnnotation:pa];
    self.centerAnnotation = pa;
    [pa release];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    centerAnnotation.coordinate = mapView.centerCoordinate;
    centerAnnotation.subtitle = [NSString stringWithFormat:@"%f, %f", centerAnnotation.coordinate.latitude, centerAnnotation.coordinate.longitude]; 
}

- (void)dealloc {
    [centerAnnotation release];
    [super dealloc];
}

@end

现在这将移动注释,但不顺利。如果您需要注解更顺畅地移动,您可以在地图视图中添加UIPanGestureRecognizerUIPinchGestureRecognizer,并在手势处理程序中更新注解:

    // (Also add UIGestureRecognizerDelegate to the interface.)

    // In viewDidLoad:
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    panGesture.delegate = self;
    [mapView addGestureRecognizer:panGesture];
    [panGesture release];

    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    pinchGesture.delegate = self;
    [mapView addGestureRecognizer:pinchGesture];
    [pinchGesture release];

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
    centerAnnotation.coordinate = mapView.centerCoordinate;
    centerAnnotation.subtitle = [NSString stringWithFormat:@"%f, %f", centerAnnotation.coordinate.latitude, centerAnnotation.coordinate.longitude]; 
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    //let the map view's and our gesture recognizers work at the same time...
    return YES;
}

【讨论】:

  • +1 来自我,仍然在上面的解决方案没有给出“静止”注释,但是对于地图解决方案上方提到的视图也是一个完美的基础。
  • 我不推荐这种使用实际注释的方法。我也不建议将注释视图添加为 MKMapView 的子视图(最好不要弄乱内部视图层次结构)。相反,将“pin”视图添加到地图视图的父级,但位于其中心上方。这将产生更平滑的效果。见stackoverflow.com/questions/20731589/…
【解决方案2】:

安娜的回答是使用标准地图视图方式中的注释将注释保持在地图中心的巧妙方法。然而,正如一位评论者指出的那样,滚动和捏合虽然好得多,但仍然显示出明显的滞后,推荐的方法是将注释视图添加为地图视图的子视图。这就是它的样子。

@interface SHCenterPinMapViewController () <MKMapViewDelegate>

@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) MKPointAnnotation *centerAnnotaion;
@property (strong, nonatomic) MKPinAnnotationView *centerAnnotationView;

@end

@implementation SHCenterPinMapViewController

- (MKPointAnnotation *)centerAnnotaion
{
    if (!_centerAnnotaion) {
        _centerAnnotaion = [[MKPointAnnotation alloc] init];
    }

    return _centerAnnotaion;
}

- (MKPinAnnotationView *)centerAnnotationView
{
    if (!_centerAnnotationView) {
        _centerAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:self.centerAnnotaion
                                                                reuseIdentifier:@"centerAnnotationView"];
    }

    return _centerAnnotationView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.mapView.delegate = self;
    [self.mapView addSubview:self.centerAnnotationView];
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [self moveMapAnnotationToCoordinate:self.mapView.centerCoordinate];
}

// These are the constants need to offset distance between the lower left corner of
// the annotaion view and the head of the pin
#define PIN_WIDTH_OFFSET 7.75
#define PIN_HEIGHT_OFFSET 5

- (void)moveMapAnnotationToCoordinate:(CLLocationCoordinate2D) coordinate
{
    CGPoint mapViewPoint = [self.mapView convertCoordinate:coordinate toPointToView:self.mapView];

    // Offset the view from to account for distance from the lower left corner to the pin head
    CGFloat xoffset = CGRectGetMidX(self.centerAnnotationView.bounds) - PIN_WIDTH_OFFSET;
    CGFloat yoffset = -CGRectGetMidY(self.centerAnnotationView.bounds) + PIN_HEIGHT_OFFSET;

    self.centerAnnotationView.center = CGPointMake(mapViewPoint.x + xoffset,
                                                   mapViewPoint.y + yoffset);
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    self.centerAnnotaion.coordinate = mapView.centerCoordinate;
    [self moveMapAnnotationToCoordinate:mapView.centerCoordinate];
}

@end

真正唯一有趣的事情是,您必须将 MKPinAnnotationView 偏移一定量以考虑左下角和针头之间的距离。我不喜欢在代码中包含这些资产相关的常量,所以如果有人能找到更好的方法来做到这一点,我会全力以赴。

我创建了一个带有地图控制器的 github 项目,该控制器执行此操作以及与使用地图视图让用户选择位置相关的其他一些事情。在这里查看:https://github.com/scottrhoyt/CenterPinMapViewController

【讨论】:

【解决方案3】:

斯威夫特版本

在课堂上:

var centerAnnotation = MKPointAnnotation()
var centerAnnotationView = MKPinAnnotationView()

在 viewDidLoad 中:

if #available(iOS 9.0, *) {
        centerAnnotationView.pinTintColor = customColor
    } else {
        // Fallback on earlier versions
        centerAnnotationView.pinColor = MKPinAnnotationColor.Red
    }
self.view.addSubview(centerAnnotationView)

在 viewDidAppear 中:

self.moveMapAnnotationToCoordinate(self.mapView.centerCoordinate)

然后:

func moveMapAnnotationToCoordinate(locate : CLLocationCoordinate2D ) {
    let mapViewPoint : CGPoint = self.mapView.convertCoordinate(locate, toPointToView: self.mapView)
    let pinWidth : CGFloat = 7.75
    let pinHeight : CGFloat = 7
    let xOffset : CGFloat = CGRectGetMidX(self.centerAnnotationView.bounds) - pinWidth
    let yOffset : CGFloat = CGRectGetMidY(self.centerAnnotationView.bounds) - pinHeight

    self.centerAnnotationView.center = CGPointMake(mapViewPoint.x - xOffset, mapViewPoint.y - yOffset)
}

要使用位置更改,请添加委托CLLocationManagerDelegate,然后:

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    self.centerAnnotation.coordinate = self.mapView.centerCoordinate
    self.moveMapAnnotationToCoordinate(self.mapView.centerCoordinate)
}

【讨论】:

  • 这段代码根本不运行。清理一下就好了
猜你喜欢
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
相关资源
最近更新 更多