Я только что написал в блоге об этом, проверьте здесь: 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
Идеи
В геофизинге сейчас происходит много интересных вещей. Некоторые идеи:
- Введите адрес и заблокируйте карту по этому адресу
- Геозоны с наложением карт
- Физические игры, которые открывают области карты, когда пользователь фактически посещает эти физические места.