Se si desidera solo per bloccare la visualizzazione della mappa in overlay, è possibile impostare regione della vista mappa per limiti della sovrapposizione e impostare scrollEnabled
e zoomEnabled
-NO
.
Ma questo non consente all'utente di scorrere o ingrandire i limiti della sovrapposizione.
Non esistono modi incorporati per limitare la visualizzazione della mappa ai limiti dell'overlay, quindi è necessario farlo manualmente. Innanzitutto, assicurati che l'oggetto MKOverlay
implementa la proprietà boundingMapRect
. Può quindi essere utilizzato nel metodo delegato regionDidChangeAnimated
per regolare manualmente la vista in base alle esigenze.
Ecco un esempio di come questo potrebbe essere fatto.
Il codice di seguito dovrebbe essere nella classe che ha il MKMapView
.
Assicurarsi che la vista mappa sia inizialmente impostata su una regione in cui l'overlay è visibile.
//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];
}
}
Ho provato questo con il built-in MKCircle
sovrapposizione e sembra funzionare bene.
EDIT:
Esso funziona bene 95% del tempo, tuttavia, Ho confermato attraverso alcuni test che potrebbe oscillare tra due posizioni, quindi immettere un ciclo infinito. Così, ho modificato un po ', credo che questo dovrebbe risolvere il problema:
// 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;
}
}
E solo nel caso in cui qualcuno è alla ricerca di una soluzione rapida MKOverlay
, qui è uno:
- (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;
}
Grazie! Questo ha fatto il trucco. – mag725
ha funzionato abbastanza bene. non gestisce i casi in cui si effettua una panoramica (scorrimento, scorrimento o altro) della vista al di fuori dei limiti. – horseshoe7
@ horseshoe7, la vista ritorna nell'overlay dopo aver terminato il gesto? Inoltre, la mappa deve iniziare all'interno della sovrapposizione affinché funzioni sopra.Se è necessario limitare _while_ l'utente sta spostando la mappa, è possibile essere in grado di farlo utilizzando un UIPanGestureRecognizer e controllando la nuova area della mappa nel gestore di gesti. – Anna