Обнаружение, когда пользователь прокручивает MKMapView на определенное расстояние? - PullRequest
6 голосов
/ 29 марта 2011

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

Я не уверен, какие методы использовать.

Я думаю, что было бы просто создать прямоугольник и посмотреть, содержит ли прямоугольник текущую центральную точку, однако я должен нацелиться на IOS 3, поэтому я не могу использовать многие новые API Mapkit.

Я пытался сработать с CLLocation и с помощью distanceFrom между текущим центром карты и местоположением пользователя, но я пытаюсь выяснить, составляет ли это расстояние определенный процент.

Ответы [ 3 ]

15 голосов
/ 30 января 2012

Лично я считаю более полезным, когда кто-то может опубликовать фрагмент кода или общую прозу о том, как можно это сделать. Вот что я придумал - грубо взломанный, чтобы просто лучше ответить на этот вопрос:

В заголовочном файле у меня есть:

#define SCROLL_UPDATE_DISTANCE          80.00

и, на мой взгляд (это и делегат для CLLocationManagerDelegate, MKMapViewDelegate):

// this method is called when the map region changes as a delegate of MKMapViewDelegate
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    NSLog(@"regionDidChangeAnimated");
    MKCoordinateRegion mapRegion;   
    // set the center of the map region to the now updated map view center
    mapRegion.center = mapView.centerCoordinate;

    mapRegion.span.latitudeDelta = 0.3; // you likely don't need these... just kinda hacked this out
    mapRegion.span.longitudeDelta = 0.3;

    // get the lat & lng of the map region
    double lat = mapRegion.center.latitude;
    double lng = mapRegion.center.longitude;

    // note: I have a variable I have saved called lastLocationCoordinate. It is of type
    // CLLocationCoordinate2D and I initially set it in the didUpdateUserLocation
    // delegate method. I also update it again when this function is called
    // so I always have the last mapRegion center point to compare the present one with 
    CLLocation *before = [[CLLocation alloc] initWithLatitude:lastLocationCoordinate.latitude longitude:lastLocationCoordinate.longitude];
    CLLocation *now = [[CLLocation alloc] initWithLatitude:lat longitude:lng];

    CLLocationDistance distance = ([before distanceFromLocation:now]) * 0.000621371192;
    [before release];
    [now release];

    NSLog(@"Scrolled distance: %@", [NSString stringWithFormat:@"%.02f", distance]);

    if( distance > SCROLL_UPDATE_DISTANCE )
    {
        // do something awesome
    }

    // resave the last location center for the next map move event
    lastLocationCoordinate.latitude = mapRegion.center.latitude;
    lastLocationCoordinate.longitude = mapRegion.center.longitude;

}

Надеюсь, что отправит вас в правильном направлении.

distanceFromLocation - iOS 3.2 и более поздние версии. initWithLatitude - iOS 2.0 и позже. MKCoordinateRegion - это iOS 3.0 и более поздние версии. MKMapView centerCoordinate - это iOS 3.0 и более поздние версии.

Также - пожалуйста, не стесняйтесь прыгнуть и установить меня прямо там, где я ошибся Я сам все это выясняю - но пока мне это удается.

Надеюсь, это кому-нибудь поможет.

3 голосов
/ 30 марта 2011

Первый урок: не задавайте вопросы поздно вечером на SO.

Второй урок: вы можете достичь этого просто путем создания CGPoint из текущего местоположения пользователя и CGPoint из центра MapView.

С двумя точками просто вычислите расстояние и посмотрите, превышает ли оно определенный порог.

Вы также можете построить CGRect вокруг центра карты и проверить CGRectContainsPoint, если это проще.*

- (BOOL) isUserPointInsideMapCenterRegion
{
    CLLocation * ul = _mapView.userLocation.location;

    CGPoint userPoint = [_mapView convertCoordinate: ul.coordinate toPointToView: _mapView];
    CGPoint mapPoint = [_mapView convertCoordinate: _mapView.centerCoordinate toPointToView: _mapView];

    if (fabs(userPoint.x - mapPoint.x) > MAP_CENTER_RECTANGLE_SIZE || fabs(userPoint.y - mapPoint.y) > MAP_CENTER_RECTANGLE_SIZE)
    {
        return NO;
    }

    return YES;
}
2 голосов
/ 21 марта 2013

Я понимаю, что этот вопрос уже немного устарел, но я чувствую, что ответ, описанный в на этот другой вопрос , является более надежным, поскольку метод делегата может быть запущен по любой причине. Использование UIPanGestureRecognizer для обнаружения прокрутки означает, что пользователь прокручивал карту вручную, и он может проверять, прокрутила ли карта X пикселей, вместо того, чтобы полагаться на метры, что означает, что пользователь прокручивал более или менее в зависимости от уровня масштабирования. ,

https://stackoverflow.com/a/11675587/159758

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...