Как я знаю, когда setregion на MKMapView не будет запускать regionWillChange / regionDidChange - PullRequest
4 голосов
/ 18 января 2010

Я работаю над некоторым кодом iPhone MapKit, который запускает некоторые события, когда изменяются границы карты (в основном, некоторые запросы к внешнему серверу). Есть один крайний случай, который я не могу решить. Когда пользователи вводят новый адрес, я использую setRegion, чтобы увеличить это местоположение, а затем вычисляю границы карты и запрашиваю эти координаты на моем внешнем сервере. Я всегда вызываю setRegion, однако, есть один крайний случай, когда он не сработает. То есть, когда пользователь волшебным образом выбирает тот же адрес, который лежит в текущем центре карты, когда эта карта масштабируется точно в тот же регион. Конечно, такая возможность редка, но ее легко реализовать с помощью следующего кода:

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

Это было бы эквивалентно разрешению пользователю сбросить значок в центре текущей карты и запустить запрос на мой сервер на основании этого. К сожалению, поскольку логика кода зависит от изменения региона (что я и сделал, чтобы пользователи могли легко перемещаться по карте и не нужно явно нажимать кнопку обновления), мне нужно обойти это. Как я могу узнать, когда setRegion был вызван, но он не будет запускать regionWillChange / regionDidChange. Можно ли как-нибудь переопределить функцию?

EDIT: Как я прокомментировал первый ответ, я попытался определить, когда регион не изменится, используя следующий код:

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

К сожалению, когда я устанавливаю searchLocation в центр текущей карты, я получаю следующие результаты:

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

В разных случаях ошибка немного отличается, но, вообще говоря, даже когда область немного отличается, например, этот setRegion или более, regionDidChange, не запускаются. Кто-нибудь может объяснить почему? Или как я мог бы обнаружить это правильно. Примечание: я также пытался с mapView.centerCoordinate, но получаю похожие ошибки, и я хочу знать только, когда регион НЕ изменится (если centerCoordinate одинаков, уровень масштабирования / регион все еще может быть другим).

Ответы [ 3 ]

0 голосов
/ 30 сентября 2012

Это взломанный обходной путь, который мне подходит.

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
}

Как вы, наверное, заметили, я сделал предположение, что точность после шестого знака после запятой слишком мала ( до 11 мм ), чтобы визуальное изменение требовалось на карте. (даже при самом высоком уровне масштабирования).

0 голосов
/ 18 апреля 2017

У меня работают следующие коды:

    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")
    }
0 голосов
/ 18 января 2010

Почему бы вам просто не позвонить regionWill / Изменился ли вручную код, который устанавливает новое местоположение на карте, если он обнаруживает точку, на которую он установит карту, которая будет текущим центром?

...