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