Как добавить аннотацию по центру карты в iPhone? - PullRequest
7 голосов
/ 28 июня 2011

У меня в приложении есть MAP-представление, и я хочу добавить значок аннотации (красный штифт) в центре карты.
Теперь, когда пользовательский штифт вида карты прокрутки должен корректироваться с центром в соответствии с этим.
Каксделать это?
Спасибо

Ответы [ 3 ]

10 голосов
/ 28 июня 2011

Если вы хотите использовать реальную аннотацию вместо обычного вида, расположенного над центром вида карты, вы можете:

  • использовать класс аннотаций с настраиваемым свойством координат (например, предопределенный класс 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

Теперь это будет перемещать аннотацию, но не плавно. Если вам нужно, чтобы аннотация перемещалась более плавно, вы можете добавить UIPanGestureRecognizer и UIPinchGestureRecognizer к виду карты, а также обновить аннотацию в обработчике жестов:

    // (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;
}
5 голосов
/ 08 марта 2014

Ответ Анны - умный подход к центру аннотации на карте с использованием аннотаций стандартным способом просмотра карты. Однако, как отметил один из комментаторов, прокрутка и сжатие, хотя и намного лучше, по-прежнему показывают заметную задержку, и рекомендуемый подход заключается в добавлении представления аннотации в качестве подпредставления представления карты. Вот как это выглядит.

@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

0 голосов
/ 05 января 2016

Swift версия

В классе:

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)

InDidAppear:

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)
}
...