重写融云里的地图定位

2021-12-24  本文已影响0人  简单Timor

最近用了融云IM的SDK,但是里面关于定位部分,iOS没有位置搜索, android是有的。所以...自定义呗。

先看下效果: RPReplay_Final1640311497.gif

主要基于这三个SDK:

#import <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapSearchKit/AMapSearchKit.h>

1. 处理扩展。

在聊天界面处理下面代码。

/*!
 扩展功能板的点击回调

 @param pluginBoardView 输入扩展功能板View
 @param tag             输入扩展功能(Item)的唯一标示
 */
- (void)pluginBoardView:(RCPluginBoardView *)pluginBoardView clickedItemWithTag:(NSInteger)tag {
    switch (tag) {
           case PLUGIN_BOARD_ITEM_LOCATION_TAG: {
               RCDLocationViewController *vc = [[RCDLocationViewController alloc] init];
               vc.delegate = self;
               UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:vc];
               navi.modalPresentationStyle = UIModalPresentationOverFullScreen;
               [self presentViewController:navi animated:YES completion:nil];
           }
               break;
               
           default:
               [super pluginBoardView:pluginBoardView clickedItemWithTag:tag];
               break;
       }
}
/*!
 地理位置选择完成之后的回调

 @param locationPicker 地理位置选取的ViewController
 @param location       位置的二维坐标
 @param locationName   位置的名称
 @param mapScreenShot  位置在地图中的缩略图

 @discussion
 如果您需要重写地理位置选择的界面,当选择地理位置完成后,需要调用此回调通知RCConversationViewController定位已完成,可以进一步生成位置消息并发送。
 */
- (void)locationPicker:(RCLocationPickerViewController *)locationPicker
     didSelectLocation:(CLLocationCoordinate2D)location
          locationName:(NSString *)locationName
         mapScreenShot:(UIImage *)mapScreenShot {
    RCLocationMessage *locationMessage =
    [RCLocationMessage messageWithLocationImage:mapScreenShot location:location locationName:locationName];
    [self sendMessage:locationMessage pushContent:nil];
}

     didSelectLocation:(CLLocationCoordinate2D)location
          locationName:(NSString *)locationName
         mapScreenShot:(UIImage *)mapScreenShot

这个方法是原来融云里面的delegate,就没有去单独写了。

2. 自定义地图界面


#import <RongIMKit/RongIMKit.h>
#import "XNViewController.h"

NS_ASSUME_NONNULL_BEGIN
/*!
 地理位置选择完成之后的回调
 */
@protocol RCDLocationViewControllerDelegate <NSObject>

/*!
 地理位置选择完成之后的回调

 @param locationPicker 地理位置选取的ViewController
 @param location       位置的二维坐标
 @param locationName   位置的名称
 @param mapScreenShot  位置在地图中的缩略图

 @discussion
 如果您需要重写地理位置选择的界面,当选择地理位置完成后,需要调用此回调通知RCConversationViewController定位已完成,可以进一步生成位置消息并发送。
 */
- (void)locationPicker:(RCLocationPickerViewController *)locationPicker
     didSelectLocation:(CLLocationCoordinate2D)location
          locationName:(NSString *)locationName
         mapScreenShot:(UIImage *)mapScreenShot;

@end

@interface RCDLocationViewController : XNViewController
@property(nonatomic, weak) id <RCDLocationViewControllerDelegate> delegate;

@end

NS_ASSUME_NONNULL_END
#import "RCDLocationViewController.h"
#import <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapSearchKit/AMapSearchKit.h>

@interface RCDLocationViewController ()<UITableViewDelegate, UITableViewDataSource, AMapSearchDelegate, AMapLocationManagerDelegate, MAMapViewDelegate, MAMapViewDelegate, UITextFieldDelegate>
//定位
@property (nonatomic, strong) AMapLocationManager *locationManager;
//地图
@property (nonatomic, strong) MAMapView *mapView;
//大头针
@property (nonatomic, strong) MAPointAnnotation *annotation;
//逆地理编码
@property (nonatomic, strong) AMapReGeocodeSearchRequest *regeo;
//逆地理编码使用的
@property (nonatomic, strong) AMapSearchAPI *search;
@property (nonatomic, strong) NSMutableArray<AMapPOI *> *dataArrary;

@property (nonatomic, strong) UITableView *mTableView;

@property (nonatomic, assign) CLLocationCoordinate2D currentGPSCoordinate;

@property (nonatomic, strong) UITextField *textFiled;

@property (nonatomic, copy) NSString *currentCity;

@end

@implementation RCDLocationViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.mapView.showsUserLocation = true;
    self.mapView.userTrackingMode = MAUserTrackingModeFollow;
    [self addObserver];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}

- (void)ActionForBackButton:(UIButton *)button {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)setUpUI {
    [self setNaviTitle:@"选择位置"];
    [self addNavigationBarBackButton:nil normal:IMAGENAME(@"ic_back") selected:IMAGENAME(@"ic_back")];
    [self.view addSubview:self.mapView];
    [self.view addSubview:self.textFiled];
    [self.view addSubview:self.mTableView];
    self.search.delegate = self;
    [self startLocation];
    [self.nextButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
}

- (void)startLocation {
    _currentGPSCoordinate = kCLLocationCoordinate2DInvalid;
    [self showHUD:@"定位中..."];
    [self.mapView removeAnnotations:_mapView.annotations];
    __weak typeof (self) weakself = self;
    [self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
        [weakself hideHUD];
        if (error) {
            [weakself showHUDError:@"定位失败,请重新定位"];
        }
        if (regeocode != nil) {
            NSLog(@"%@",[NSString stringWithFormat:@"地址信息:\n%@",regeocode]);
        }
        self.currentGPSCoordinate = location.coordinate;
        // 添加定位点的大头针
        MAPointAnnotation *annotation = [[MAPointAnnotation alloc]init];
        annotation.coordinate = self.currentGPSCoordinate;
        [self.mapView addAnnotation:annotation];
        [annotation setLockedToScreen:YES];
        annotation.lockedScreenPoint = CGPointMake(self.mapView.bounds.size.width/2, self.mapView.bounds.size.height/2);
        // 设置地图
        [self.mapView setZoomLevel:15.5 animated:YES];
        [self.mapView selectAnnotation:annotation animated:YES];
        [self.mapView setCenterCoordinate:self.currentGPSCoordinate animated:NO];
        [self searchAllPOIAround:self.currentGPSCoordinate];
        
    }];
}

- (void)searchAllPOIAround:(CLLocationCoordinate2D) coordinate{
    AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init];
    request.sortrule = 0;
    request.offset = 30;
    request.location = [AMapGeoPoint locationWithLatitude:coordinate.latitude longitude:coordinate.longitude];
    request.radius = 500;
    [self.search AMapPOIAroundSearch:request];
}

//地图区域改变完成后会调用此接口
- (void)mapView:(MAMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    //非法的时候需返回
    if (!CLLocationCoordinate2DIsValid(_currentGPSCoordinate)) {
        return;
    }
    
    [self searchAllPOIAround: _mapView.centerCoordinate];
    //搜索POI
    [self searchAllPOIAround:_mapView.centerCoordinate];
}

///注意:大头针是跟TableView的Cell一样具有重用机制的,处理不好界面会有很多消失不去的大头针。
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation {
    if ([annotation isKindOfClass:[MAPointAnnotation class]]) {
        NSString *pointReuseIndetifier = @"pointReuseIndetifier";
        MAPinAnnotationView *annotationView = ((MAPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndetifier]);
        if (annotationView == nil) {
            annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndetifier];
        }
        annotationView.canShowCallout = NO;
        annotationView.animatesDrop = YES;
        [annotationView setDraggable:NO];
        return annotationView;
    }
    return nil;
}

- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response {
    if (!_dataArrary) {
        _dataArrary = [[NSMutableArray alloc]init];
    }
    [_dataArrary removeAllObjects];
    [_dataArrary addObjectsFromArray:response.pois];
    _currentCity = _dataArrary[0].city;
    [_mTableView reloadData];
}

//搜索框激活时,使用提示搜索
-(void)updateSearchResultsForSearchController:(UITextField *)searchTextField
{
    //发起输入提示搜索
    AMapInputTipsSearchRequest *tipsRequest = [[AMapInputTipsSearchRequest alloc] init];
   //关键字
    tipsRequest.keywords = searchTextField.text;
   //城市
    tipsRequest.city = _currentCity;

    //执行搜索
    [_search AMapInputTipsSearch: tipsRequest];

}

//实现输入提示的回调函数
- (void)onInputTipsSearchDone:(AMapInputTipsSearchRequest*)request response:(AMapInputTipsSearchResponse *)response
{
    if(response.tips.count == 0)
    {
        return;
    }
    //通过AMapInputTipsSearchResponse对象处理搜索结果
    //先清空数组
    if (!self.dataArrary) {
        self.dataArrary = [[NSMutableArray alloc]init];
    }
    [self.dataArrary removeAllObjects];
    for (AMapTip *p in response.tips) {
        //把搜索结果存在数组
        [self.dataArrary addObject:p];
    }
//    _isSelected = NO;
    //刷新表视图
    [self.mTableView reloadData];
}

#pragma tableViewDelegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return _dataArrary.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"adressCell" forIndexPath:indexPath];
    AMapPOI *poi = _dataArrary[indexPath.section];
    cell.textLabel.font = [UIFont systemFontOfSize:14];
    cell.textLabel.textColor = UIColor.grayColor;
    cell.textLabel.text = poi.name;
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    AMapPOI *poi = _dataArrary[indexPath.section];
    ///这里处理选中
    if (_delegate != nil) {
//        @autoreleasepool {
            //    "http://restapi.amap.com/v3/staticmap?location=" + longitude + "," + latitude +
            //                "&zoom=17&scale=2&size=150*150&markers=mid,,A:" + longitude + ","
            //                + latitude + "&key=" + "AMAP_KEY";
            NSString *url = [self toImage:poi.location.longitude latitude:poi.location.latitude];
//            UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]]];
            NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
        UIImage *image = [UIImage imageWithData:data];


            [_delegate locationPicker:nil didSelectLocation:CLLocationCoordinate2DMake(poi.location.latitude, poi.location.longitude) locationName:poi.name mapScreenShot:image];
//        }
        
    }
    [self dismissViewControllerAnimated:YES completion:nil];
    
}



#pragma textFiled Delegate

- (void)textFieldDidEndEditing:(UITextField *)textField {
    [self updateSearchResultsForSearchController:textField];
}

#pragma setter and getter

- (AMapLocationManager *)locationManager {
    if (!_locationManager) {
        _locationManager = [[AMapLocationManager alloc]init];
        [_locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
        _locationManager.locationTimeout = 5;
        _locationManager.reGeocodeTimeout = 5;
        _locationManager.delegate = self;
    }
    return _locationManager;
}

- (AMapReGeocodeSearchRequest *)regeo {
    if (!_regeo) {
        _regeo = [[AMapReGeocodeSearchRequest alloc]init];
        _regeo.requireExtension = YES;
    }
    return _regeo;
}

- (AMapSearchAPI *)search {
    if (!_search) {
        _search = [[AMapSearchAPI alloc]init];
        _search.delegate = self;
    }
    return _search;
}

- (UITableView *)mTableView {
    if (!_mTableView) {
        _mTableView = [[UITableView alloc]initWithFrame:CGRectMake(0, kScreenH/2 + 100,kScreenW, (kScreenH - NaviBarStatusBarHeight)/2 - 100 )];
        _mTableView.delegate = self;
        _mTableView.dataSource = self;
        _mTableView.backgroundColor = UIColor.clearColor;
        _mTableView.showsHorizontalScrollIndicator = NO;
        [ZQShareMethod setExtraCellLineHidden:_mTableView];
        [_mTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"adressCell"];
        
    }
    return _mTableView;
}

- (MAMapView *)mapView {
    if (!_mapView) {
        _mapView = [[MAMapView alloc]initWithFrame:CGRectMake(0, NaviBarStatusBarHeight, kScreenW, (kScreenH - NaviBarStatusBarHeight)/2)];
        _mapView.delegate = self;
        _mapView.compassOrigin = CGPointMake(_mapView.compassOrigin.x, 22);
        _mapView.scaleOrigin = CGPointMake(_mapView.scaleOrigin.x, 22);
        _mapView.showsScale = NO;
        _mapView.zoomLevel = 15;
    }
    return _mapView;
}

- (UITextField *)textFiled {
    if (!_textFiled) {
        _textFiled = [[UITextField alloc]initWithFrame:CGRectMake(15, kScreenH/2 + 50, kScreenW - 30, 40)];
        _textFiled.delegate = self;
        _textFiled.borderStyle = UITextBorderStyleRoundedRect;
        _textFiled.placeholder = @"搜索地点";
        _textFiled.returnKeyType = UIReturnKeyDone;
        [_textFiled addTarget:self action:@selector(updateSearchResultsForSearchController:) forControlEvents:UIControlEventValueChanged];
    }
    return _textFiled;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField{
    [self.view endEditing:YES];
    return YES;
}


- (NSString *)toImage:(double)longitude  latitude:(double)latitude {
    return [NSString stringWithFormat:@"https://restapi.amap.com/v3/staticmap?location=%f,%f&zoom=12&size=300*150&&markers=mid,,A:%f,%f&key=%@",longitude,latitude,longitude,latitude,[NSString stringWithFormat:@"893421fc7552922a75fabd1cf7823c68"]];
}

- (void)addObserver{
    //增加监听,当键盘出现或改变时收出消息
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    
    //增加监听,当键退出时收出消息
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
}
//当键盘出现或改变时调用
- (void)keyboardWillShow:(NSNotification *)aNotification {
    NSDictionary* info = [aNotification userInfo];
    //kbSize即為鍵盤尺寸 (有width, height)
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;//得到鍵盤的高度
    self.textFiled.frame = CGRectMake(15, kScreenH - (kbSize.height + SafeAreaBottomHeight + 10), kScreenW - 30, 40);
}

//当键退出时调用
- (void)keyboardWillHide:(NSNotification *)aNotification {
    [self dismissTouchView];
    self.textFiled.frame = CGRectMake(15, kScreenH/2 + 50, kScreenW - 30, 40);

}
- (void)doinsomethingwithtouchViewdismiss {
    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
}
@end

比较忙,时间匆匆。等空了再来完善吧,只此记录。

上一篇下一篇

猜你喜欢

热点阅读