Поддерживать координату центра при защемлении MKMapView
Если вы щелкаете для увеличения/уменьшения масштаба в приложении Apple Maps при отслеживании местоположения устройства, компонент "панорамирования" жесты щепотка игнорируется, а синий индикатор положения остается фиксированным в центре экрана. Это не тот случай, когда используется простой MKMapView
.
Предполагая, что у меня уже есть местоположение пользователя, как я могу добиться этого эффекта? Я попытался сбросить центральную координату в методах делегата regionDid/WillChangeAnimated:
, но они вызываются только в начале и в конце жестов. Я также попытался добавить подкласс UIPinchGestureRecognizer
, который сбрасывает центральную координату, когда касания перемещаются, но это приводило к устранению сбоев.
Изменить: Для тех, кто заинтересован, для меня работает следующее.
// CenterGestureRecognizer.h
@interface CenterGestureRecognizer : UIPinchGestureRecognizer
- (id)initWithMapView:(MKMapView *)mapView;
@end
// CenterGestureRecognizer.m
@interface CenterGestureRecognizer ()
- (void)handlePinchGesture;
@property (nonatomic, assign) MKMapView *mapView;
@end
@implementation CenterGestureRecognizer
- (id)initWithMapView:(MKMapView *)mapView {
if (mapView == nil) {
[NSException raise:NSInvalidArgumentException format:@"mapView cannot be nil."];
}
if ((self = [super initWithTarget:self action:@selector(handlePinchGesture)])) {
self.mapView = mapView;
}
return self;
}
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
return NO;
}
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
return NO;
}
- (void)handlePinchGesture {
CLLocation *location = self.mapView.userLocation.location;
if (location != nil) {
[self.mapView setCenterCoordinate:location.coordinate];
}
}
@synthesize mapView;
@end
Затем просто добавьте его в свой MKMapView
:
[self.mapView addGestureRecognizer:[[[CenterGestureRecognizer alloc] initWithMapView:self.mapView] autorelease]];
Ответы
Ответ 1
Когда пользователь зажимает экран на самом устройстве (в отличие от симулятора), он вызывает как поворот, так и жест щепотки - пинч содержит элемент "масштабирования" движения, а кастрюля содержит вертикальные и горизонтальное изменение. Вам нужно перехватить и заблокировать панорамирование, а это значит, что используйте UIPanGestureRecognizer
.
Установите scrollEnabled
в NO
, затем добавьте координату UIPanGestureRecognizer
в reset. Комбинация блокирует панорамирование с одним пальцем и компонент панорамирования пинча.
Изменить, чтобы добавить дополнительные сведения и после просмотра кода: touchesMoved:withEvent
вызывается после того, как панорама уже началась, поэтому, если вы измените центр MKMapView, вы получите хеши- которые вы описали. Вам действительно нужно создать UIPanGestureRecognizer
с целевым действием, например:
UIPanGestureRecognizer *pan = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(didRecognizePan)] autorelease];
pan.delegate = self;
[self.mapView addGestureRecognizer:pan];
... а затем добавьте метод didRecognizePan
к вашему контроллеру и сделайте там сброс центра.
Ответ 2
Догадайтесь, но попробовали ли вы установить scrollEnabled
на NO
в начале regionWillChangeAnimated:
?
Ответ 3
Просто догадка. В начале регионаWillChangeAnimated: сохраните текущую область карты, затем непрерывно обновляйте область через NSTimer, используя self.myMapView.region = theSavedRegion или аналогичный. Затем отключите таймер при вызове regionDidChangeAnimated:
Однако у вас может возникнуть проблема, когда обновление региона с помощью NSTimer вызывает повторение запроса regionWillChangeAnimated.
Попробуйте и посмотрите, что произойдет.