使用苹果自带地图获取当前位置及周围信息

天朝的网络在XXX的干预下,我们很多内容都不能正常访问,需要翻墙。处在这样一个大的局域网环境之下,作为IT行业的我们很是苦恼,如果做的应用要世界通用,那就是痛苦了,需要考虑很多。例如:如果我们做一个地图应用,兼容中国和外国。要么使用国内地图+Google,要么就是使用苹果自带地图。今天主要介绍使用苹果自带地图获取用户当前位置及用户周围信息,地图移动时,地图中间大头针一直在中间,移动结束后有下落定位的动画效果并更新当前位置及用户周围信息。需要真机测试查看效果。

先看效果:
gif动画是在模拟器上录制,由于模拟器不能获取周围信息,所以一直在转菊花。要看实际效果需要真机查看。

IMG_2365.PNG

步骤

  1. 添加库MapKit.framework

    模拟器效果展示

  2. 打开地图功能。


    真机截图
  3. 代码实现。

  • 在用户位置显示完成后添加一个固定的ImageView在地图正中间。
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    NSLog(@"userLocation:longitude:%f---latitude:%f",userLocation.location.coordinate.longitude,userLocation.location.coordinate.latitude);
    if (!haveGetUserLocation) {
        if (self.mapView.userLocationVisible) {
            haveGetUserLocation = YES;
            [self getAddressByLatitude:userLocation.coordinate.latitude longitude:userLocation.coordinate.longitude];
            [self addCenterLocationViewWithCenterPoint:self.mapView.center];
        }
        
    }
}


-(void)addCenterLocationViewWithCenterPoint:(CGPoint)point
{
    if (!imgView) {
        imgView = [[UIImageView alloc]initWithFrame:CGRectMake([UIScreen mainScreen].bounds.size.width/2, 100, 18, 38)];
        imgView.center = point;
        imgView.image = [UIImage imageNamed:@"map_location"];
        imgView.center = self.mapView.center;
        [self.view addSubview:imgView];
    }
    
}

  • 获取当前位置周围信息,苹果提供了一个请求方法,MKLocalSearch。其官方介绍为:

An MKLocalSearch object initiates a map-based search operation and delivers the results back to your app asynchronously. Search objects are designed to perform one search operation only. To perform several different searches, you must create separate instances of this class and start them separately.
也就是说我们如果要搜索不同的类型需要分别创建多个实例进行操作。

如果我们要搜索周围100米餐厅代码如下:

    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coordinate,100, 100);
    MKLocalSearchRequest *request = [[MKLocalSearchRequest alloc]init];
    request.region = region;
    request.naturalLanguageQuery = @"Restaurants";
    MKLocalSearch *localSearch = [[MKLocalSearch alloc]initWithRequest:request];
    [localSearch startWithCompletionHandler:^(MKLocalSearchResponse *response, NSError *error){
        if (!error) {
            //do something.
        }else{
            //do something.
        }
    }];

其中naturalLanguageQuery就是要搜索的关键字,我试过的所有关键字有cafe, supermarket,village,Community,Shop,Restaurant,School,hospital,Company,Street,Convenience store,Shopping Centre,Place names,Hotel,Grocery store每个关键字搜索返回结果只有10条,如果当前范围无搜索结果,则扩散搜索范围。如果你想列出周围所有相关位置信息,我认为需要尽可能的把所有的能够想到的关键字都举例出来进行搜索,搜索完成后进行经纬度比较然后刷选出范围内的相关位置。而且由于数据来源问题,很多位置信息都没有!当然如果你只兼容国内,还是使用百度或者腾讯地图算了。

  • 根据经纬度获取位置相关信息。
    CLLocation *location=[[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        if (!error) {
            dispatch_async(dispatch_get_main_queue(), ^{
            //do something.
            });
        }else{
            //do something.
        }
        
    }];
  • 下落定位动画效果
     imgView.center = CGPointMake(mapCenter.x, mapCenter.y-15);
     [UIView animateWithDuration:0.2 animations:^{
            imgView.center = mapCenter;
        }completion:^(BOOL finished){
            if (finished) {
                [UIView animateWithDuration:0.05 animations:^{
                    imgView.transform = CGAffineTransformMakeScale(1.0, 0.8);
                    
                }completion:^(BOOL finished){
                    if (finished) {
                        [UIView animateWithDuration:0.1 animations:^{
                            imgView.transform = CGAffineTransformIdentity;
                        }];
                    }
                }];
            }
      }];

这里我的思路是三个动画效果组合以达到大头针下落定位的效果。

  • 获取用户滑动地图操作。
    MKMapViewDelegate中有个方法在滑动结束后可以回调如下所示:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated

因为回调是在展示的地图区域改变后调用,所以使用它有个缺点就是在最开始初始化地图并定位到用户所在位置时,它会被反复回调。所以很难确定用户是否是滑动。所以这里我们需要知道用户是否和地图有过滑动后导致它的回调。如何做呢?这里有两种方法以供参考。
方法一:这里你是否想起UIScrollView,如果我们想获取touch事件,我们应该怎么做,没错就是继承后重写touch方法,然后把toush事件传递下去。代码如下:

@implementation ZHMapView

#pragma mark - touchs
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    [[self nextResponder] touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    [[self nextResponder] touchesMoved:touches withEvent:event];
}

-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
    [[self nextResponder] touchesEnded:touches withEvent:event];
  
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
     [super touchesCancelled:touches withEvent:event];
    [[self nextResponder]touchesCancelled:touches withEvent:event];
}

方法二:我在修改 navigationBar 底部线条颜色总结这篇文章中有用到查看View层次结构找到隐藏属性并对它进行操作。没错这里也是一样的道理,先看mapview层次结构例如如下所示:


这里我们可以发现_MKMapContentView里面有个手势数组,没错就是它了。我们获取它并对他进行操作,代码如下所示:

//打印完后我们发现有个View带有手势数组其类型为_MKMapContentView获取Span手势
    for (UIView *view in self.mapView.subviews) {
        NSString *viewName = NSStringFromClass([view class]);
        if ([viewName isEqualToString:@"_MKMapContentView"]) {
            UIView *contentView = view;//[self.mapView valueForKey:@"_contentView"];
            for (UIGestureRecognizer *gestureRecognizer in contentView.gestureRecognizers) {
                if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
                    [gestureRecognizer addTarget:self action:@selector(mapViewSpanGesture:)];
                }
            }

        }
    }

  • 加载时UITableView顶部展示菊花展示,这个原理和我们做分页展示时,滑动到底部或顶部有个菊花展示的道理一样。代码如下
#pragma mark - Private Methods
-(void)resetTableHeadView
{
    if (infoArray.count>0) {
        self.showTableView.tableHeaderView = nil;
    }else{
        UIView *view = [[UIView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 30.0)];
        view.backgroundColor = self.showTableView.backgroundColor;
        UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        indicatorView.center = view.center;
        [indicatorView startAnimating];
        [view addSubview:indicatorView];
        self.showTableView.tableHeaderView = view;
        
    }
}

下载地址

GitHub

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,574评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,623评论 4 59
  • 那天我和老友们接他放假,他在我们那所城市最好的高中就读,说实话在和他商量好要接他之前的几个小时里我心里特别激...
    夏嗯阅读 235评论 0 1
  • 一 宇宙一何衰,兴亡皆稊米。 草木知吾醉,深深封石肆。 二 故园植新韭,采采与人依。 向无春日暖,安得清嫩毗。 复...
    专治各种嘚瑟阅读 279评论 1 2
  • 你们曾经吃过最棒的秘制鸡腿饭究竟有多好吃呢?照烧的口感,鲜嫩的鸡肉,松脆的表皮,烤的金黄的鸡肉上刷着一层浓稠的焦糖...
    味库美食视频阅读 334评论 1 4