17

我有以下问题:

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

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

我已经对这个主题进行了很多研究,但我没有找到一个好的解决方案。

任何帮助表示赞赏!

最好的问候, 克里斯蒂安

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

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
4

3 回答 3

14

在尝试了不同的有限 MKMapView 方法后,我得出结论,使用 mapDidChange,如果你的中心点超出边界,则重置效果最好,动画:是

这就是我的做法(使用新西兰纬度/长跨度/中心)。

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{ 
  if ((mapView.region.span.latitudeDelta > 15.589921 ) || (mapView.region.span.longitudeDelta > 175.836914) ) {
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914);

    MKCoordinateSpan spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500 );

    MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ);

    [mapView setRegion: NZRegion animated: YES];
  }

 if (abs(abs(mapView.region.center.latitude) - 41.162114) > (13.589921 / 2) ) {
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914);

    MKCoordinateSpan spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500 );

    MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ);

    [mapView setRegion: NZRegion animated: YES];

  }

  if (abs(abs(mapView.region.center.longitude) - 172.836914) > (14.062500 / 2) ) {
    CLLocationCoordinate2D centerCoord = CLLocationCoordinate2DMake(-41.162114, 172.836914);

     MKCoordinateSpan  spanOfNZ = MKCoordinateSpanMake(13.589921, 14.062500 );

     MKCoordinateRegion NZRegion = MKCoordinateRegionMake(centerCoord, spanOfNZ);

     [mapView setRegion: NZRegion animated: YES];
  }
}
于 2011-05-27T02:56:38.030 回答
6

通过实施:

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

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

查看该答案以获取有关如何执行此操作的示例。


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

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

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

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

于 2011-04-15T19:34:35.233 回答
0

我知道这是一个很老的问题,但为了避免无限循环,你可以尝试这样的事情:https ://stackoverflow.com/a/4126011/1234011

如果是你设置了值,基本上设置一个标志以防止回调再次触发。

于 2013-05-01T17:15:09.607 回答