Si vous voulez juste geler l'affichage de la carte à la superposition, vous pouvez définir la région de la vue sur la carte aux limites de la superposition et mettre scrollEnabled
et zoomEnabled
-NO
.
Mais cela ne permettra pas à l'utilisateur de faire défiler ou de zoomer à l'intérieur des limites de l'overlay.
Il n'existe pas de méthodes intégrées pour restreindre la vue de la carte aux limites de la superposition, vous devez donc le faire manuellement. Tout d'abord, assurez-vous que votre objet MKOverlay
implémente la propriété boundingMapRect
. Cela peut ensuite être utilisé dans la méthode déléguée regionDidChangeAnimated
pour ajuster manuellement la vue selon les besoins.
Voici un exemple de la façon dont cela pourrait être fait.
Le code ci-dessous doit appartenir à la classe MKMapView
.
Assurez-vous que l'affichage de la carte est initialement défini sur une région où la superposition est visible.
//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];
}
}
J'ai essayé avec le MKCircle
intégré superposition et semble bien fonctionner.
EDIT:
Il ne fonctionne 95% du temps, cependant, je l'ai confirmé par des tests qu'il pourrait osciller entre deux emplacements, puis entrer dans une boucle infinie. Donc, j'édita un peu, je pense que cela devrait résoudre le problème:
// 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;
}
}
Et juste au cas où quelqu'un est à la recherche d'une solution MKOverlay
rapide, voici une:
- (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;
}
Merci! Cela a fait l'affaire. – mag725
a très bien fonctionné. ne gère pas les cas où vous faites un panoramique (glisser, défiler, quoi que) la vue en dehors de vos limites cependant. – horseshoe7
@ Horseshoe7, la vue réapparaît-elle dans la superposition après la fin du mouvement? En outre, la carte doit commencer à l'intérieur de la superposition pour que le dessus fonctionne.Si vous devez limiter _while_ l'utilisateur déplace la carte, vous pouvez le faire en utilisant un UIPanGestureRecognizer et en vérifiant la nouvelle région de la carte dans le gestionnaire de gestes. – Anna