仿微信的发送位置功能

376 阅读3分钟

近期公司项目中接入了腾讯的IM 为了让聊天更完善 决定加入微信的发送位置功能

先附一张最终实现的效果图


Screen Shot 2023-11-15 at 16.38.33.png

  • 废话不多说 开始上干货 我们用的是腾讯地图就以腾讯地图为例
  1. 引入腾讯地图的库
  pod 'Tencent-MapSDK', '5.1.0'
  pod 'Tencent-MapVisualPlugin', '3.1.0'
  pod 'Tencent-MapFoundation', '>=3.3.0'
  pod 'Tencent-MapUtils', '1.2.3'
  
  1. 这个看自己实际需求吧 我新建的是一个控制器
#import <QMapKit/QMapKit.h>
#import <QMapKit/QMSSearchKit.h>
2.1 用到的代理 <QMapViewDelegate, QMSSearchDelegate, UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource,UITextFieldDelegate>
2.2 地图展示与搜索用到的类
@property (nonatomic, strong) QMapView *mapView;
@property (nonatomic, strong) QMSSearcher *mapSearcher;
@property (nonatomic, strong) QPointAnnotation *annotation;
@property (nonatomic, strong) QPinAnnotationView *pinView;

  1. 地图+ 地图搜索类的初始化
- (QMSSearcher *)mapSearcher {
    if (_mapSearcher == nil) {
        _mapSearcher = [[QMSSearcher alloc] initWithDelegate:self];
    }
    return _mapSearcher;
}
    self.mapView = [[QMapView alloc]
                    initWithFrame: CGRectMake(0,
                                              0,
                                              kScreenW,
                                             XH_Height(1040))];
    self.mapView.delegate = self;
    // 备注: (不知道什么原因腾讯地图初始化的时候必要有一个位置 作为它的中心点, 我最开始使用的iOS系统定位直接放上去地图就是不居中 后来想了一下应该是坐标系不同意的原因 就转了一下 就居中了)
    #(坐标转化我用的是这个工具)
    pod 'JZLocationConverter'
    
    CGFloat lats = [[PSHelper shareManager].lats floatValue]; // 转化后的坐标
    CGFloat lonts = [[PSHelper shareManager].lonts floatValue];
    self.mapView.centerCoordinate = CLLocationCoordinate2DMake(lats,lonts);
    self.mapView.handDrawMapEnabled = YES;
    self.mapView.showsTraffic = YES;
    self.mapView.zoomLevel        = 15;
    [self.view addSubview:self.mapView];
    self.mapView.showsPoi = YES;
    [self setupPointAnnotation];
    
  1. 设置定位大头针的方法
- (void)setupPointAnnotation {

    CGFloat lats =  [[PSHelper shareManager].lats floatValue];
    CGFloat lonts = [[PSHelper shareManager].lonts floatValue];
    _annotation = [[QPointAnnotation alloc] init];
    _annotation.coordinate = CLLocationCoordinate2DMake(lats, lonts);
    [self.mapView addAnnotation:_annotation];
    self.localLats = [NSString stringWithFormat:@"%f",self.mapView.centerCoordinate.latitude];
    self.localLonts = [NSString stringWithFormat:@"%f",self.mapView.centerCoordinate.longitude];
  
}

 
- (QAnnotationView *)mapView:(QMapView *)mapView viewForAnnotation:(id<QAnnotation>)annotation {
    if ([annotation isKindOfClass:[QPointAnnotation class]]) {
        static NSString *pinIndentifier = @"PinIndentifier";
        _pinView = (QPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pinIndentifier];
        if (_pinView == nil) {
            _pinView = [[QPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIndentifier];
            _pinView.image = [UIImage imageNamed:@"msg_icon_map"];
        }
        return _pinView;
    }
    return nil;
}

  1. 点击地图定位点地图回到当前位置的方法

- (void)curLocalClickAction {

    [self.curLocalBtn setImage:[UIImage imageNamed:@"msg_icon_zoom_selected"] forState:UIControlStateNormal];
    self.mapView.centerCoordinate = CLLocationCoordinate2DMake(self.curLats,self.curLonts);
    self.localLats = [NSString stringWithFormat:@"%f",self.curLats];
    self.localLonts = [NSString stringWithFormat:@"%f",self.curLonts];
    [self searchCurrentLocationWithKeyword:@""];
    
}
  • 到这就是定位涉及的所有方法
  1. 基于当前位置的搜索功能
- (void)mapViewRegionChange:(QMapView *)mapView {

    // 更新位置
    _annotation.coordinate = mapView.centerCoordinate;
    self.localLats = [NSString stringWithFormat:@"%f",mapView.centerCoordinate.latitude];
    self.localLonts = [NSString stringWithFormat:@"%f",mapView.centerCoordinate.longitude];
    
}

// 请求当前位置的地标
- (void)mapView:(QMapView *)mapView regionDidChangeAnimated:(BOOL)animated gesture:(BOOL)bGesture {
    if (bGesture == YES) {
        _searchBar.text = @"";
        // 判断与上次坐标是否相同
        CLLocationCoordinate2D centerCoord = mapView.centerCoordinate;
        if (_lastLocation.latitude == centerCoord.latitude && _lastLocation.longitude == centerCoord.longitude) {
            return;
        }
        [self.curLocalBtn setImage:[UIImage imageNamed:@"msg_icon_zoom_default"] forState:UIControlStateNormal];
        // 请求当前地点
        [self searchCurrentLocationWithKeyword:@""];
    }
    _annotation.coordinate = mapView.centerCoordinate;
}

- (void)searchCurrentLocationWithKeyword:(NSString *)keyword {

    CLLocationCoordinate2D centerCoord = self.mapView.centerCoordinate;
    QMSPoiSearchOption *option = [[QMSPoiSearchOption alloc] init];
    if (keyword.length > 0) {
        option.keyword = keyword;
    }
    option.boundary = [NSString stringWithFormat:@"nearby(%f,%f,2000,1)", centerCoord.latitude, centerCoord.longitude];
    // 这里可以设置具体的筛选类型 具体可以看下腾讯地图官方文档
//    [option setFilter:@"category="];
    [self.mapSearcher searchWithPoiSearchOption:option];
    
}

- (void)searchWithPoiSearchOption:(QMSPoiSearchOption *)poiSearchOption didReceiveResult:(QMSPoiSearchResult *)poiSearchResult {

    NSLog(@"基于当前位置的搜索结果:%@", poiSearchResult);
    if (poiSearchResult.count == 0) {
        return;
    }
    // 地图移动到搜索结果的第一个位置
    if (_searchBar.text.length > 0) {
        _selectedIndex = 0;
        // 搜索结果对象 展示数据的使用会用到  title 搜索到的位置名称  _distance  搜索到的位置距离当前位置的距离
        QMSPoiData *firstData = poiSearchResult.dataArray[0];
        _annotation.coordinate = firstData.location;
        [self.mapView setCenterCoordinate:firstData.location animated:YES];
    } else {
        _selectedIndex = -1;
    }
    _searchResultArray = poiSearchResult.dataArray;
    [_searchResultTableView reloadData];
    
}

- (void)searchWithSearchOption:(QMSSearchOption *)searchOption didFailWithError:(NSError*)error {
    DLog(@"地理位置搜索失败的回调=====%@",error);
}

  1. 发送位置的时候使用的腾讯的地图截图功能
[self.mapView takeSnapshotInRect:@“想要展示的截图大小” completion:^(UIImage *resultImage) {
           /// 返回的是一个image 对象
        }];

基于腾讯地图发送位置的功能大致就这些了 剩余的就是一些根据搜索结果展示的代码了

**这里有一点需要注意的开发时申请腾讯地图的时候 最好用企业号 不然搜索的权限个人号每天好像就一次 搜索结果是搜不出来的 别的就没啥了 按照流程走就好了 **