美文网首页
重写融云里的地图定位

重写融云里的地图定位

作者: 简单Timor | 来源:发表于2021-12-24 10:15 被阅读0次

    最近用了融云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
    
    

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

    相关文章

      网友评论

          本文标题:重写融云里的地图定位

          本文链接:https://www.haomeiwen.com/subject/yerlqrtx.html