Comment puis-je savoir quand setRegion sur un MKMapView ne se déclenche pas regionWillChange / regionDidChange

voix
4

Je travaille sur un code iPhone MapKit qui se déclenche au large des événements lorsque les limites du changement de carte (essentiellement des requêtes à un serveur externe). Il y a un cas limite, je ne peux pas sembler résoudre. Lorsque les utilisateurs entrent dans une nouvelle adresse que j'utilise setRegion pour zoomer sur cet endroit et ensuite je calcule les limites de la carte et interroger mon serveur externe avec les coordonnées. Je fais toujours appel setRegion cependant, il y a un cas de bord quand il ne se déclenche pas. Ce, est, lorsqu'un utilisateur se produit comme par magie pour sélectionner la même adresse exacte qui se trouve au centre actuel de la carte, lorsque cette carte est zoomée exactement la même région. Bien sûr, cette possibilité est rare, mais il est facile réalisable avec le code suivant:

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];

Ce serait l'équivalent de permettre à l'utilisateur de déposer une épingle au centre de la carte actuelle et de déclencher une requête à mon serveur sur cette base. Malheureusement, parce que la logique de code dépend de la région en mutation (que je l'ai fait pour que les utilisateurs peuvent facilement déplacer sur la carte et ne pas avoir à appuyer sur un bouton explicitement de rafraîchissement), je besoin d'un travail autour. Comment puis-je savoir quand setRegion a été appelé, mais ce ne sera pas le feu regionWillChange / regionDidChange. Puis-je remplacer la fonction d'une façon?

EDIT: Comme je l'ai commenté la première réponse, j'ai essayé de détecter le moment où la région ne changerait en utilisant le code suivant:

//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];

Malheureusement, quand je mets le searchLocation être le centre de la carte actuelle, je reçois les résultats suivants:

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

Dans différents cas, l'erreur est légèrement différente, mais de façon générale, même si la région est un peu différent comme celui-ci setRegion ou morever, regionDidChange, ne se déclenche pas. Quelqu'un peut-il expliquer pourquoi? Ou comment je pourrais aller sur la détection de ce bien. Note: J'ai aussi essayé avec mapView.centerCoordinate mais je reçois des erreurs similaires, et je veux seulement savoir quand la région ne sera pas changer (si le centerCoordinate est le même niveau de zoom / région peut encore être différente).

Créé 18/01/2010 à 19:02
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
0

Les codes suivants fonctionne pour moi:

    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")
    }
Créé 18/04/2017 à 16:41
source utilisateur

voix
0

Ceci est une solution de contournement piraté up qui semble bien fonctionner pour moi.

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
}

Comme vous l' avez sans doute remarqué, je l' ai fait l'hypothèse que la précision après la sixième place décimale est beaucoup trop insignifiante ( jusqu'à 11 mm ) pour un changement visuel être nécessaire sur la carte (même à son niveau de zoom le plus élevé).

Créé 30/09/2012 à 12:14
source utilisateur

voix
0

Pourquoi ne pas appeler simplement regionWill / Est-ce modifier manuellement à partir du code qui établit le nouvel emplacement de carte si elle détecte le point, il fixerait la carte pour serait le centre actuel?

Créé 18/01/2010 à 21:20
source utilisateur

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