热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS-如何将MapView限制在特定区域?-iOS-HowtolimittheMapViewtoaspecificregion?

Ihavethefollowingproblem:我有以下问题:Ihaveadrawnmap(image)whichIaddtotheMapViewasan

I have the following problem:

我有以下问题:

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中。这个模式没有任何的问题。但是我需要将MapView限制在覆盖区域,这样用户就不能在这个区域之外滚动/缩放。但是在覆盖层的“界限”内滚动/缩放应该是可能的——这意味着我不能仅为MapView禁用缩放/滚动。

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.

关于这个话题有什么想法/解决办法吗?使用MapView/-Kit的原因是我需要向自定义映射添加各种POIs。如果只是使用ImageView+ScrollView来表示定制映射,这可能会变得更加复杂。

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

关于这个话题我已经研究了很多,但是我没有找到一个好的解决方案。

Any help is appreciated!

任何帮助都是赞赏!

Best Regards, Christian

最好的祝福,基督教

Edit: This is our solution: You supply a topleft and a bottomright coordinate to limit the map. The (minimum) zoomlevel is also limited. I've deactivated decelerating and you are able to bounce a bit out of the map (for better performance/ux). I added a ~1km grey border to the overlay so the user isnÄt able to see the orignal worldmap of google.

编辑:这是我们的解决方案:您提供一个左上角和右下角的坐标来限制映射。zoomlevel也是有限的。我已经停用了减速,您可以从地图上反弹一点(为了更好的性能/用户体验)。我在覆盖层添加了一个~1km的灰色边框,这样用户就可以看到谷歌的原始世界地图了。

LimitedMapView.h:

LimitedMapView.h:

#import 
#import 


@interface LimitedMapView : MKMapView {

}

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


@end

LimitedMapView.m:

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.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)) 

3 个解决方案

#1


6  

By implementing :

通过实现:

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

-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)动画

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

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

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

看看这个答案,并给出一个例子。


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.

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

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

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

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

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.

注意:虽然协议是公共的,但是MKMapView实现是未知的,并且可能与iOS版本不同,所以使用respondsToSelector: before检查更安全。您必须调用超级实现,否则映射将无法正常工作。

#2


13  

After trying different ways of limited MKMapView I've concluded that using mapDidChange, and resetting if you're center point goes outside of the boundaries works best, with animated: YES

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

Here's how I do it (Using the New Zealand lat/Long span/center).

我是这样做的(使用新西兰的lat/Long span/center)。

- (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];
  }
}

#3


0  

I know this is a pretty old question, but to avoid the infinite loop you could try something like this: https://stackoverflow.com/a/4126011/1234011

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

Basically set a flag to prevent the callback from firing again if it was you who set the value.

基本上设置一个标志,如果设置值的是您,则防止回调再次触发。

  • Ken

推荐阅读
  • 涉及的知识点-ViewGroup的测量与布局-View的测量与布局-滑动冲突的处理-VelocityTracker滑动速率跟踪-Scroller实现弹性滑动-屏幕宽高的获取等实现步 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • [转载]从零开始学习OpenGL ES之四 – 光效
    继续我们的iPhoneOpenGLES之旅,我们将讨论光效。目前,我们没有加入任何光效。幸运的是,OpenGL在没有设置光效的情况下仍然可 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • IB 物理真题解析:比潜热、理想气体的应用
    本文是对2017年IB物理试卷paper 2中一道涉及比潜热、理想气体和功率的大题进行解析。题目涉及液氧蒸发成氧气的过程,讲解了液氧和氧气分子的结构以及蒸发后分子之间的作用力变化。同时,文章也给出了解题技巧,建议根据得分点的数量来合理分配答题时间。最后,文章提供了答案解析,标注了每个得分点的位置。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了css回到顶部按钮相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
只喝大瓶的雪碧
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有