首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MKMapView边界?

MKMapView边界?
EN

Stack Overflow用户
提问于 2010-01-18 09:06:26
回答 3查看 1.5K关注 0票数 0

任何人都知道在MKMapView上实现边界的简单方法。例如,我想告诉地图它只能停留在一个区域。我希望用户能够滚动,但让他们停止当他们到达某个纬度/经度。我试着使用willChangeRegion:委托,但这把我搞砸了。谢谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-30 01:47:24

我刚刚写了一篇关于这方面的博文,请在这里查看:http://blog.jamgraham.com/blog/2012/04/29/adding-boundaries-to-mkmapview/

我参与了一个要求锁定MKMapView边界的项目。由于苹果没有提供开箱即用的解决方案,我们只能将MKMapView子类化。这非常简单,让您可以访问地图中的UIScrollView和MKMapView中的其他有趣对象。

现在想看看代码吗?你可以在这里找到:https://github.com/jamgraham/geoFencer

锁定MKMapView的边界一般需要两个步骤。第一个是将缩放级别锁定为最小和最大。第二个是防止用户滚动到你创建的铸造厂之外。让我们通过查看需要重写的委托来遍历这些

1.缩放级别

这是非常直接的。目标是在用户缩放时检查缩放级别,并在用户停止缩放时再次检查缩放级别。

代码语言:javascript
复制
 -(void)scrollViewDidZoom:(UIScrollView *)scrollView;
 -(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;

2.滚动边界

这有点复杂。当用户在UIScrollView中滚动地图时,我们希望确保他们不会超出边界,如果他们超出边界,我们希望阻止他们。当我们看到用户离开边界时,我们可以通过将地图重新定位到边界来实现这一点。当用户感觉自己撞到了墙上,而不是地图来回跳动时,这种情况发生得足够快。以下是我们需要注意的委派:

代码语言:javascript
复制
 -(void)scrollViewDidScroll:(UIScrollView *)scrollView;
 -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

3.复制和粘贴

请随意复制并粘贴下面的自定义MKMapView。在显示地图的UIViewController中,自定义地图视图需要设置边界

ViewController.m

代码语言:javascript
复制
    //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

代码语言:javascript
复制
@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

代码语言:javascript
复制
#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

想法

现在在地理围栏上有很多很酷的东西。一些想法:

  • 输入一个地址,并使用map overlays
  • Physical游戏将地图锁定到该地址,当用户实际访问这些物理位置时,这些游戏会解锁地图的区域。
票数 2
EN

Stack Overflow用户

发布于 2010-01-19 00:12:08

因此,我将继续回答我自己的问题,并说没有EASY方法来实现此行为。你不仅要检查边界,还要检查滚动的方向,控制台不断地告诉我:最后一次触摸后滚动但scrollViewDidEndDragging:willDecelerate:未被调用!我想我还有更多的研究要做。

票数 0
EN

Stack Overflow用户

发布于 2014-03-11 16:01:08

我一直在做一些研究,发现没有简单的方法可以做到这一点。

因此,我的解决方案是将地图锁定在某个区域,并使用包含MKMapView的scrollView进行放大和缩小。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2083357

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档