我有以下问题:
我有一个“绘制地图”(图像),我将其添加到MapView作为叠加层。没有问题..但我需要将MapView限制为Overlay区域,因此用户无法在此区域之外滚动/缩放..但应该可以在“边界内”滚动/缩放“覆盖 - 意味着我不能只为MapView禁用缩放/滚动。
这个主题有什么想法/解决方案吗?使用MapView / -Kit的原因是我需要将各种POI添加到自定义地图。仅使用ImageView + ScrollView呈现自定义地图时,这可能会变得更加复杂。
我已经对这个主题进行了很多研究,但我没有找到一个很好的解决方案。
感谢任何帮助!
最诚挚的问候, 基督教
编辑:这是我们的解决方案: 您提供了一个topleft和一个底部坐标来限制地图。 (最小)缩放级别也是有限的。我已经停用减速功能,你可以从地图中弹出一点(为了更好的性能/ ux)。我在叠加层上添加了一个〜1km的灰色边框,这样用户就无法看到google的orignal worldmap。
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
答案 0 :(得分:13)
在尝试了有限的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];
}
}
答案 1 :(得分:6)
通过实施:
-(void) mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
您应该可以将区域重置为特定区域。
查看at that answer以获得如何执行此操作的示例。
另一个解决方案,它会带来更精确的事件,但更复杂 (我目前正在成功使用此功能以满足其他需求)是子类MKMapView
并覆盖UIScrollViewDelegate
协议。
如果您这样做,请务必按照以下方式调用super
实施:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
if ([super respondsToSelector:@selector(scrollViewWillBeginDragging:)])
[super scrollViewWillBeginDragging:scrollView];
// do what you want
}
注意:虽然协议是公开的,但MKMapView
实施是未知的,可能与iOS版本不同,因此以前检查respondsToSelector:
更安全。你必须调用超级实现,否则Map将无法正常工作。
答案 2 :(得分:0)
我知道这是一个非常古老的问题,但要避免无限循环,你可以尝试这样的事情:https://stackoverflow.com/a/4126011/1234011
基本上设置一个标志,以防止回调再次触发,如果你是谁设置了值。