Границы MKMapView? - PullRequest
       9

Границы MKMapView?

0 голосов
/ 18 января 2010

Каждый знает простой способ реализации границ в MKMapView. Например, я хочу сказать карте, что она может находиться только в одной области. Я хочу, чтобы у пользователя была возможность прокрутки, но он должен остановиться, когда они достигнут определенной широты / долготы. Я пытался использовать willChangeRegion: делегат, но это меня облажало. Спасибо.

Ответы [ 3 ]

2 голосов
/ 29 апреля 2012

Я только что написал в блоге об этом, проверьте здесь: http://blog.jamgraham.com/blog/2012/04/29/adding-boundaries-to-mkmapview/

Я работал над проектом с требованием заблокировать границы MKMapView. Поскольку не существует готового решения от Apple, мы оставили подкласс MKMapView. Это довольно просто и дает вам доступ к UIScrollView, который живет на карте, и другим забавным объектам в MKMapView.

Хотите посмотреть код сейчас? Это доступно здесь: https://github.com/jamgraham/geoFencer

Блокировка границ MKMapView вызывает два основных шага. Сначала нужно зафиксировать уровень масштабирования до минимума и максимума. Второе - запретить пользователю прокручивать страницы за пределами созданного вами литейного цеха. Давайте пройдемся по ним, посмотрев на делегатов, которых мы должны переопределить

1. Уровень масштабирования

Это довольно просто. Целью является проверка уровня масштабирования по мере увеличения и повторения пользователем, когда пользователь прекращает масштабирование.

 -(void)scrollViewDidZoom:(UIScrollView *)scrollView;
 -(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;

2. Границы прокрутки

Это немного сложнее. Поскольку пользователь прокручивает карту в UIScrollView, мы хотим убедиться, что они не выходят за границы, и если они это сделают, мы хотим остановить их. Мы можем достичь этого, переместив карту на границу, когда увидим, что пользователь выходит за границу. Это происходит достаточно быстро, когда пользователи чувствуют, что ударились о стену, а не дергались вокруг карты. Вот делегаты, за которыми нам нужно следить:

 -(void)scrollViewDidScroll:(UIScrollView *)scrollView;
 -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

3. Копировать и вставить

Не стесняйтесь копировать и вставлять пользовательский MKMapView ниже. В UIViewController, который показывает карту, пользовательскому представлению карты необходимо установить границы

ViewController.m

    //Set map boundaries
    mapView.showsUserLocation = YES;
    [mapViewsetZoomMax:0.015551];
    [mapViewsetZoomMin: 0.346360];
    mapView.top = 37.773498;
    mapView.bottom = 37.745130;
    mapView.left = -122.430365;
    mapView.right = -122.401623;

GeoMapView.h

@interface GeoMapView : MKMapView
{
    MKCoordinateRegion cordRegion;
    CLLocationCoordinate2D oldcenter;
    double left;
    double right;
    double top;
    double bottom;
    double zoomMax;
    double zoomMin;
}

-(void)checkZoom;
-(void)checkScroll;

@property (nonatomic) double left;
@property (nonatomic) double right;
@property (nonatomic) double top;
@property (nonatomic) double bottom;
@property (nonatomic) double zoomMax;
@property (nonatomic) double zoomMin;

@end

GeoMapView.m

#import "GeoMapView.h"

@implementation GeoMapView
@synthesize  left, right, top, bottom,zoomMax,zoomMin;

- (id)initWithFrame:(CGRect)frame
{
    self = [superinitWithFrame:frame];
    if (self) {

    }
    returnself;
}

-(void)scrollViewDidZoom:(UIScrollView *)scrollView {
    [selfcheckZoom];    
}


-(void)checkZoom{
    UIScrollView * scroll = [[[[selfsubviews] objectAtIndex:0] subviews] objectAtIndex:0];

    if (scroll.zoomScale < zoomMax) {
        NSLog(@"Reached Max Zoom");
        [scroll setZoomScale:zoomMaxanimated:NO];
    }

    if (scroll.zoomScale >= zoomMin) {
        NSLog(@"Reached Min Zoom");
        [scroll setZoomScale:zoomMinanimated:NO];

    }
}

-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
    UIScrollView * scroll = [[[[selfsubviews] objectAtIndex:0] subviews] objectAtIndex:0];

    if (scroll.zoomScale > zoomMin) {
        [scroll setZoomScale:zoomMinanimated:NO];
    }   
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {

    [selfcheckScroll];

}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [selfcheckScroll];
}

-(void)checkScroll{
    @try{
        cordRegion = self.region;

        CLLocationCoordinate2D center = self.region.center;
        CLLocationCoordinate2D northWestCorner, southEastCorner;
        northWestCorner.latitude  = center.latitude  + (self.region.span.latitudeDelta  / 2.0);
        northWestCorner.longitude = center.longitude - (self.region.span.longitudeDelta / 2.0);
        southEastCorner.latitude  = center.latitude  - (self.region.span.latitudeDelta  / 2.0);
        southEastCorner.longitude = center.longitude + (self.region.span.longitudeDelta / 2.0);

        CLLocationCoordinate2D newcenter;
        newcenter.latitude = self.region.center.latitude;
        newcenter.longitude = self.region.center.longitude;

        //LEFT
        CLLocationDegrees farLeft = left;
        CLLocationDegrees snapToLeft = farLeft + (self.region.span.longitudeDelta  / 2.0);
        if (northWestCorner.longitude < farLeft)
        {
            newcenter.longitude = snapToLeft;
            cordRegion = self.region;
        }

        //RIGHT
        CLLocationDegrees r = (self.region.span.longitudeDelta / 2.0);
        CLLocationDegrees farRight = right;
        CLLocationDegrees snapToRight = farRight - r;
        if (southEastCorner.longitude > farRight)
        {
            newcenter.longitude = snapToRight;
        }

        //TOP
        CLLocationDegrees farTop = top;
        CLLocationDegrees snapToTop = top - (self.region.span.latitudeDelta  / 2.0);
        if (northWestCorner.latitude > farTop)
        {
            newcenter.latitude = snapToTop;
        }

        //BOTTOM
        CLLocationDegrees farBottom = bottom;
        CLLocationDegrees rr = (self.region.span.latitudeDelta  / 2.0);
        CLLocationDegrees snapToBottom = bottom + rr;
        if (southEastCorner.latitude < farBottom)
        {            
            newcenter.latitude = snapToBottom;
        }

        [selfsetCenterCoordinate:newcenter  animated:NO];

    }
    @catch (NSException *e) {
    }
    @finally {}
}


@end

Идеи

В геофизинге сейчас происходит много интересных вещей. Некоторые идеи:

  • Введите адрес и заблокируйте карту по этому адресу
  • Геозоны с наложением карт
  • Физические игры, которые открывают области карты, когда пользователь фактически посещает эти физические места.
0 голосов
/ 11 марта 2014

Я провел какое-то исследование и обнаружил, что нет простого способа сделать это.

Таким образом, мое решение состоит в том, чтобы заблокировать карту в определенной области и иметь scrollView, который содержит MKMapView для увеличения и уменьшения масштаба.

0 голосов
/ 18 января 2010

Итак, я собираюсь ответить на свой вопрос и сказать «нет». ЛЕГКИЙ способ реализовать это поведение. Мало того, что вы должны проверить границы, но вы также должны проверить направление прокрутки, и консоль постоянно говорит мне: последнее касание после прокрутки, но scrollViewDidEndDragging: willDecelerate: не было вызвано! I думаю, у меня еще много исследований ...

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