iOS - 如何将 MapView 限制到特定区域? [英] iOS - How to limit the MapView to a specific region?

查看:23
本文介绍了iOS - 如何将 MapView 限制到特定区域?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下问题:

我有一个绘制的地图"(图像),我将其作为叠加添加到 MapView.没问题..但我需要将 MapView 限制在覆盖的区域内,因此用户无法在该区域外滚动/缩放..但应该可以在边界"内滚动/缩放" 的叠加层 - 意味着我不能只是禁用 MapView 的缩放/滚动.

I have a "drawn map" (image) which I add to the MapView as an Overlay. No Problem with that.. but I need to limit the MapView to the region of the Overlay, so a user isn't able to scroll/zoom outside of this region.. but it should be possible to scroll/zoom inside the "bounds" of the overlay - means I cannot just disable zoom/scrolling for the MapView.

是否有关于此主题的任何想法/解决方案?使用 MapView/-Kit 的原因是我需要在自定义地图中添加各种 POI.当仅使用 ImageView+ScrollView 来呈现自定义地图时,这可能会变得更加复杂.

Are there any ideas/solution on this topic? The reason for using the MapView/-Kit is that I need to add various POIs to the custom map. This may become more complex when just using an ImageView+ScrollView for presenting the custom map.

我对此主题进行了大量研究,但没有找到好的解决方案.

I've researched alot on this topic, but I didn't found a nice solution.

感谢任何帮助!

最好的问候,克里斯蒂安

Best Regards, Christian

这是我们的解决方案:您提供左上角和右下角坐标来限制地图.(最小)缩放级别也受到限制.我已经停用了减速功能,您可以从地图中稍微弹跳一下(以获得更好的性能/用户体验).我在叠加层中添加了约 1 公里的灰色边框,因此用户无法看到 google 的原始世界地图.

LimitedMapView.h:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>


@interface LimitedMapView : MKMapView <UIScrollViewDelegate>{

}

@property (nonatomic, assign) CLLocationCoordinate2D topLeftCoordinate;
@property (nonatomic, assign) CLLocationCoordinate2D bottomRightCoordinate;


@end

LimitedMapView.m:

#import "LimitedMapView.h"

@implementation LimitedMapView

@synthesize topLeftCoordinate, bottomRightCoordinate;

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

    if([super respondsToSelector:@selector(scrollViewDidZoom:)]) [super scrollViewDidZoom:scrollView];

    if ([self region].span.latitudeDelta > 0.002401f || [self region].span.longitudeDelta > 0.003433f) {

        CLLocationCoordinate2D center = self.centerCoordinate;
        MKCoordinateSpan span = MKCoordinateSpanMake(0.002401f, 0.003433f);

        self.region = MKCoordinateRegionMake(center, span);

    }

}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

    if([super respondsToSelector:@selector(scrollViewDidEndDragging:)]) [super scrollViewDidEndDragging:scrollView willDecelerate:decelerate];

    MKCoordinateRegion currentRegion = self.region;
    bool changeRegionLong = YES;
    bool changeRegionLat = YES;

    // LONGITUDE    
    if((currentRegion.center.longitude - (currentRegion.span.longitudeDelta/2)) < self.topLeftCoordinate.longitude) {

        currentRegion.center.longitude = (topLeftCoordinate.longitude + (currentRegion.span.longitudeDelta/2));

    } else if((currentRegion.center.longitude + (currentRegion.span.longitudeDelta/2)) > self.bottomRightCoordinate.longitude) {

        currentRegion.center.longitude = (bottomRightCoordinate.longitude - (currentRegion.span.longitudeDelta/2));

    } else {

        changeRegionLong = NO;

    }

    // LATITUDE    
    if((currentRegion.center.latitude + (currentRegion.span.latitudeDelta/2)) > self.topLeftCoordinate.latitude) {

        currentRegion.center.latitude = (topLeftCoordinate.latitude - (currentRegion.span.latitudeDelta/2));

    } else if((currentRegion.center.latitude - (currentRegion.span.latitudeDelta/2)) < self.bottomRightCoordinate.latitude) {

        currentRegion.center.latitude = (bottomRightCoordinate.latitude + (currentRegion.span.latitudeDelta/2));

    } else {

        changeRegionLat = NO;

    }

    if(changeRegionLong || changeRegionLat) [self setRegion:currentRegion animated:YES];

}

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

    [scrollView setContentOffset:scrollView.contentOffset animated:YES];
}

@end

推荐答案

通过实施:

-(void) mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated

您应该能够将区域重置为您的特定区域.

You should be able to reset region to your specific one.

查看该答案如何执行此操作的示例.

Look at that answer to have an example of how to do this.

另一个解决方案,它带来更精确的事件,但更复杂 (我目前正在成功地使用它来满足另一个需求)是子类 MKMapView 并覆盖 UIScrollViewDelegate 协议.

Another solution, that brings more precise events but is more complex (I'm currently using this successfully for another need) is to subclass MKMapView and override UIScrollViewDelegate protocol.

如果这样做,请确保像这样调用 super 实现:

If you do that, make sure to call super implementation like that :

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
  if ([super respondsToSelector:@selector(scrollViewWillBeginDragging:)])
    [super scrollViewWillBeginDragging:scrollView];
  // do what you want
}

注意:虽然协议是公开的,MKMapView 的实现是未知的,并且可能因 iOS 版本而异,因此在之前使用 respondsToSelector: 进行检查更安全.您必须调用超级实现,否则 Map 将无法正常工作.

Note: While the protocol is public, MKMapView implementation is unknown and might differ with iOS versions, so it is more safe to check with respondsToSelector: before. You must call super implementations or Map will just not work properly.

这篇关于iOS - 如何将 MapView 限制到特定区域?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆