Если вы просто хотите, чтобы заморозить вид карты на накладке, можно установить область вида карты на границы наложения и установить scrollEnabled
и zoomEnabled
в NO
.
Но это не позволит пользователю прокручивать или масштабировать границы границ наложения.
Нет встроенных способов ограничить отображение карты границами наложения, поэтому вам придется делать это вручную. Во-первых, убедитесь, что ваш объект MKOverlay
реализует свойство boundingMapRect
. Затем этот метод можно использовать в методе делегата regionDidChangeAnimated
, чтобы вручную отрегулировать представление по мере необходимости.
Вот пример того, как это можно сделать.
Код ниже должен быть в том классе, который имеет MKMapView
.
Убедитесь, что для отображения карты первоначально задана область, в которой отображается оверлей.
//add two ivars to the .h...
MKMapRect lastGoodMapRect;
BOOL manuallyChangingMapRect;
//in the .m...
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
if (manuallyChangingMapRect)
return;
lastGoodMapRect = mapView.visibleMapRect;
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
if (manuallyChangingMapRect) //prevents possible infinite recursion when we call setVisibleMapRect below
return;
// "theOverlay" below is a reference to your MKOverlay object.
// It could be an ivar or obtained from mapView.overlays array.
BOOL mapContainsOverlay = MKMapRectContainsRect(mapView.visibleMapRect, theOverlay.boundingMapRect);
if (mapContainsOverlay)
{
// The overlay is entirely inside the map view but adjust if user is zoomed out too much...
double widthRatio = theOverlay.boundingMapRect.size.width/mapView.visibleMapRect.size.width;
double heightRatio = theOverlay.boundingMapRect.size.height/mapView.visibleMapRect.size.height;
if ((widthRatio < 0.6) || (heightRatio < 0.6)) //adjust ratios as needed
{
manuallyChangingMapRect = YES;
[mapView setVisibleMapRect:theOverlay.boundingMapRect animated:YES];
manuallyChangingMapRect = NO;
}
}
else
if (![theOverlay intersectsMapRect:mapView.visibleMapRect])
{
// Overlay is no longer visible in the map view.
// Reset to last "good" map rect...
[mapView setVisibleMapRect:lastGoodMapRect animated:YES];
}
}
Я попытался это с помощью встроенного в MKCircle
наложения и, кажется, работает хорошо.
EDIT:
Это действительно работает хорошо 95% времени, однако, я подтвердил через некоторые испытания, которые она может колебаться между двумя точками, а затем войти в бесконечный цикл. Итак, я редактировал его немного, я думаю, что это должно решить проблему:
// You can safely delete this method:
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
// prevents possible infinite recursion when we call setVisibleMapRect below
if (manuallyChangingMapRect) {
return;
}
// "theOverlay" below is a reference to your MKOverlay object.
// It could be an ivar or obtained from mapView.overlays array.
BOOL mapContainsOverlay = MKMapRectContainsRect(mapView.visibleMapRect, theOverlay.boundingMapRect);
if (mapContainsOverlay) {
// The overlay is entirely inside the map view but adjust if user is zoomed out too much...
double widthRatio = theOverlay.boundingMapRect.size.width/mapView.visibleMapRect.size.width;
double heightRatio = theOverlay.boundingMapRect.size.height/mapView.visibleMapRect.size.height;
// adjust ratios as needed
if ((widthRatio < 0.6) || (heightRatio < 0.6)) {
manuallyChangingMapRect = YES;
[mapView setVisibleMapRect:theOverlay.boundingMapRect animated:YES];
manuallyChangingMapRect = NO;
}
} else if (![theOverlay intersectsMapRect:mapView.visibleMapRect]) {
// Overlay is no longer visible in the map view.
// Reset to last "good" map rect...
manuallyChangingMapRect = YES;
[mapView setVisibleMapRect:lastGoodMapRect animated:YES];
manuallyChangingMapRect = NO;
} else {
lastGoodMapRect = mapView.visibleMapRect;
}
}
И только в случае, если кто-то ищет для быстрого MKOverlay
решения, вот один:
- (void)viewDidLoad {
[super viewDidLoad];
MKCircle* circleOverlay = [MKCircle circleWithMapRect:istanbulRect];
[_mapView addOverlay:circleOverlay];
theOverlay = circleOverlay;
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay {
MKCircleView* circleOverlay = [[MKCircleView alloc] initWithCircle:overlay];
[circleOverlay setStrokeColor:[UIColor mainColor]];
[circleOverlay setLineWidth:4.f];
return circleOverlay;
}
Спасибо! Это сделал трюк. – mag725
работал неплохо. не обрабатывает случаи, когда вы просматриваете (прокручиваете, прокручиваете, как угодно) вид за пределами ваших границ. – horseshoe7
@ horseshoe7, открывается ли представление в оверлей после того, как вы закончите жест? Кроме того, карта должна начинаться внутри оверлея для работы выше.Если вам нужно ограничить _while_, пользователь перемещает карту, вы можете сделать это, используя UIPanGestureRecognizer и проверив новую область карты в обработчике жестов. – Anna