No tuve mucha suerte con ninguna de estas respuestas. Hacer mi propio pellizco simplemente entró en conflicto demasiado. Me encontré con casos en los que el zoom normal se acercaba más de lo que podía hacer con mi propio pellizco.
Originalmente, traté como el cartel original de hacer algo como:
- (void) mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
MKCoordinateRegion region = mapView.region;
//...
// adjust the region.center
//...
mapView.region = region;
}
Lo que encontré fue que eso no tuvo ningún efecto. También descubrí a través de NSLog
s que este método se activará incluso cuando configuro el region
o el centerCoordinate
programáticamente. Lo que llevó a la pregunta: "¿No sería lo anterior, si funcionara, llegar a ser infinito?"
Así que estoy haciendo conjeturas y hacer hipótesis ahora que mientras que el usuario de zoom/desplazamiento/rotación está sucediendo, MapView alguna manera suprime o ignora los cambios en la región. Algo sobre el arbitraje hace que el ajuste programático impotente.
Si eso es el problema, entonces tal vez la clave es obtener el ajuste de la región fuera de la notificación regionDidChanged:
. Y dado que cualquier ajuste desencadenará otra notificación, es importante que pueda determinar cuándo no se debe ajustar más. Esto me llevó a la siguiente implementación (donde subject
está suministrando la coordenada central que quiero permanecer en el medio):
- (void) recenterMap {
double latDiff = self.subject.coordinate.latitude self.mapView.centerCoordinate.latitude;
double lonDiff = self.subject.coordinate.longitude - self.mapView.centerCoordinate.longitude;
BOOL latIsDiff = ABS(latDiff) > 0.00001;
BOOL lonIsDiff = ABS(lonDiff) > 0.00001;
if (self.subject.isLocated && (lonIsDiff || latIsDiff)) {
[self.mapView setCenterCoordinate: self.subject.coordinate animated: YES];
}
}
- (void) mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
if (self.isShowingMap) {
if (self.isInEdit) {
self.setLocationButton.hidden = NO;
self.mapEditPrompt.hidden = YES;
}
else {
if (self.subject.isLocated) { // dispatch outside so it will happen after the map view user events are done
dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^{
[self recenterMap];
});
}
}
}
}
La demora en la que se desliza hacia atrás puede variar, pero realmente funciona bastante bien. Y permite que la interacción del mapa siga siendo al estilo de Apple mientras está sucediendo.
He tenido que hacer esto antes pero lo manejé de otra manera. Inhabilité la interacción con MKMapView y agregué reconocimientos de gestos de pellizco a una vista superior. Luego convertí los gestos de pellizco en un nivel de zoom correspondiente. Así que basta con rodar tu propio pellizco para hacer zoom funcionalmente. Al ver que esto no responde directamente a su pregunta, si es una opción viable para usted, la publicaré en las respuestas con el código. – random