¿Cómo sé cuando setRegion en una MKMapView no se disparará regionWillChange / regionDidChange

votos
4

Estoy trabajando en un código iPhone MapKit que dispara a algunos eventos cuando los límites del mapa se modifican (básicamente algunas consultas a un servidor externo). Hay un caso extremo me parece que no puede resolver. Cuando los usuarios entran en una nueva dirección que utilizo setRegion hacer zoom en ese lugar y después puedo calcular los límites del mapa y Query mi servidor externo con esas coordenadas. Siempre me llaman setRegion Sin embargo, hay un caso extremo, cuando no se disparará. Eso, es decir, cuando un usuario pasa mágicamente para seleccionar la misma dirección exacta que se encuentra en el centro actual del mapa, cuando ese mapa se reduce a exactamente la misma región. Por supuesto, esta posibilidad es poco frecuente pero es fácil de lograr con el siguiente código:

CLLocation *centerOfMap = [[CLLocation alloc] initWithLatitude:mapView.centerCoordinate.latitude longitude:mapView.centerCoordinate.longitude];
mySearchLocation.searchLocation = centerOfMap;

//Recenter and zoom map in on search location
MKCoordinateRegion region =  {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = mySearchLocation.searchLocation.coordinate;region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[self.mapView setRegion:region animated:YES];

Esto sería el equivalente de permitir al usuario dejar caer un alfiler en el centro del mapa actual y disparar una consulta a mi servidor basado en eso. Por desgracia, porque la lógica del código depende de cambiar la región (que he hecho para que los usuarios puedan desplazarse fácilmente por el mapa y no tener que pulsar un botón de actualización de forma explícita), necesito un trabajo alrededor. ¿Cómo puedo saber cuándo setRegion se ha llamado pero no va a disparar regionWillChange / regionDidChange. ¿Puedo reemplazar la función de alguna forma?

EDIT: Como me comentó en la primera respuesta, traté de detectar cuando la región no cambiaría utilizando el siguiente código:

//Recenter and zoom map in on search location
MKCoordinateRegion region =  {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = mySearchLocation.searchLocation.coordinate;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
region = [mapView regionThatFits:region]; //Not sure if this is necessary

NSLog(@diff in latitude of center %f, (mapView.region.center.latitude - region.center.latitude));
NSLog(@diff in longitude of center %f, (mapView.region.center.longitude - region.center.longitude));
NSLog(@diff in latitude span %f, (mapView.region.span.latitudeDelta - region.span.latitudeDelta));
NSLog(@diff in longitude span %f, (mapView.region.span.longitudeDelta - region.span.longitudeDelta));

[self.mapView setRegion:region animated:YES];

Por desgracia, cuando me puse la searchLocation a ser el centro del mapa actual consigo los siguientes resultados:

diff in latitude of center 0.000000
diff in longitude of center 0.000016
diff in latitude span -0.000000
diff in longitude span 0.000000

En diferentes casos el error es ligeramente diferente pero en general, incluso cuando la región es ligeramente diferente como esto setRegion o morever, regionDidChange, no se dispara. ¿Alguien puede explicar por qué? O cómo podría ir sobre la detección de este adecuadamente. Nota: También probé con mapView.centerCoordinate pero me da errores similares, y yo sólo quiero saber cuando la región no cambiará (si el centerCoordinate es lo mismo el nivel de zoom / región todavía puede ser diferente).

Publicado el 18/01/2010 a las 19:02
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
0

Los siguientes códigos funciona para mí:

    let predictRect = mapView.convertRegion(mapView.regionThatFits(THE_REGION_YOU_WANT_TO_SET), toRectTo: mapView)

    if predictRect.origin.x.rounded() == 0 && predictRect.origin.y.rounded() == 0
        && predictRect.size.width.rounded() == mapView.bounds.width
        && predictRect.size.height.rounded() == mapView.bounds.height
    {
        debugPrint("setRegion same, will not trigger region change event")
    }
Respondida el 18/04/2017 a las 13:41
fuente por usuario

votos
0

Se trata de una solución hackeado que parece funcionar bien para mí.

MKCoordinateRegion currentRegion = mapView.region;

// Capture the instances where setRegion will not be fired
BOOL regionLatitudeSame = (int)(currentRegion.center.latitude*1000000) == (int)(region.center.latitude*1000000);
BOOL regionLongitudeSame = (int)(currentRegion.center.longitude*1000000) == (int)(region.center.longitude*1000000);
BOOL regionSame = regionLatitudeSame && regionLongitudeSame;
if (regionSame)
{
    // Safe to assume that regionWillChange/regionDidChange WON'T be called
}

Como te habrás dado cuenta, he hecho la suposición de que la precisión después de la sexta posición decimal es demasiado insignificante ( hasta 11 mm ) para un cambio visual que se requiere en el mapa (incluso en su nivel más alto de zoom).

Respondida el 30/09/2012 a las 12:14
fuente por usuario

votos
0

¿Por qué no llamas a regionWill / ¿Cambió de forma manual desde el código que está estableciendo la nueva ubicación del mapa si detecta el punto que establecería el mapa para sería el centro actual?

Respondida el 18/01/2010 a las 21:20
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more