美文网首页
最近接触的技术点二

最近接触的技术点二

作者: 一米押金 | 来源:发表于2020-12-16 10:16 被阅读0次

    其实今年我也是才进入到工作岗位不久,因为瘟疫来袭,我所在的城市又被称为“瘟疫之源”,一路之下,我竟然好几个月没了,工作,我们是被戏称“49年9月30号入KuoMinTang”的人,但是为了生存,有些事情,无可奈何

    总之进入正题

    查看平面图详情的功能

    有一个需求是要查看一个楼层平面图的功能,就是点击图片,展示的是一个比较大的图,但是我实际上显示的是比较小(虽然后端用Html语言,传入的图片比较大,可能是apple在对webView上进行了适配)虽然可以伸缩,但是网页也不方便给别人看,特别是年纪稍微大点的老人,我到后来请教到的办法就是,用scrollView + UIImageView这个体系,UIImageView用sd_webimage加载图,来实现这个功能

     NSString *urlStr = [NSString stringWithFormat:@"http://192.168.0.25:8091%@",self.inHospital.Image_url];
        UIScrollView *scrollView = [[UIScrollView alloc]init];
        scrollView.frame = CGRectMake(0, NAVH + STATUSH + 60, Screen_Width, Screen_Height - NAVH - STATUSH - 60);
        [self.view addSubview:scrollView];
        self.scrollView = scrollView;
        // 设置最大伸缩比例
        self.scrollView.maximumZoomScale = 2.0;
        // 设置最小伸缩比例
        self.scrollView.minimumZoomScale = 0.5;
        self.scrollView.delegate = self;
        
        UIImageView *imageView = [[UIImageView alloc]init];
        [self.scrollView addSubview:imageView];
        self.urlImageV = imageView;
        [[SDWebImageManager sharedManager]loadImageWithURL:[NSURL URLWithString:urlStr] options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
            self.urlImageV.image = image;
            CGFloat imageWidth = image.size.width * 0.3;
            CGFloat imageHeight = image.size.height * 0.3;
            CGFloat screenW = self.scrollView.bounds.size.width;
            CGFloat screenH = self.scrollView.bounds.size.height;
            self.urlImageV.frame = CGRectMake(0, 0, imageWidth, imageHeight);
            self.scrollView.contentSize = self.urlImageV.bounds.size;
            CGFloat offsetX = self.scrollView.contentSize.width * 0.5 - screenW * 0.5;
            [self.scrollView scrollRectToVisible:CGRectMake(offsetX, 0, screenW, screenH) animated:YES];
        }];
    

    然后调用代理方法(注意:上面的urlStr是模型数据,对应调用即可)

    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
        return self.urlImageV;
    }
    

    在一个需要webView的底部添加一个原生控件的情况

    当时需要一个用户在webView里需要填表,webView的高度要获取之后,我才能在后续添加一个原生控件,所以我得知道如何获取高度,之前有看到在- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation这个代理方法获取,但是我似乎没能及时获取到,所以采取的第二个方法,就是KVO

    -(void)setupKVO{
             // 添加kvo监听webview的scrollView.contentSize变化
            [self.webView addObserver:self forKeyPath:@"scrollView.contentSize" options:NSKeyValueObservingOptionNew context:nil];
    }
    
    // 使用kvo监听到的contensize变化,之所以在这里设置,因为webview加载的内容多的时候 是一段一段加载初开的,所以webview的contensize是实时变化的,所以在这里监听到可以以达到实时改变,不至于页面卡顿
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
        if (object == self.webView && [keyPath isEqual:@"scrollView.contentSize"]) {
            self.wbContentHeight = self.webView.scrollView.contentSize.height;
            [self.webView mas_updateConstraints:^(MASConstraintMaker *make) {
                make.height.mas_equalTo(self.wbContentHeight);
            }];
        }
    }
    
    
    - (void)dealloc{
        if (self.information) {
            [self.webView removeObserver:self forKeyPath:@"scrollView.contentSize" context:nil];
        }
    }
    

    iOS14UIPageControl的问题

    这个是有个网友给我留言我突然想起来了这个也是个问题,因为之前想采纳他的建议去设置,但是发现我似乎又看到了原生的点,又有自己设置的线,所以我后续用了另外一个网友的内容,所以在此复制过来了,先感谢他(先创建一个分类)

    #import <UIKit/UIKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    /**
     结合runtime 自定义UIPageControl
     */
    @interface UIPageControl (Fix4iOS14)
    
    
    /** 设置page control图片 */
    - (void)kn_SetCurrentImage:(UIImage *)currentImage pageImage:(UIImage *)pageImage;
    
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "UIPageControl+Fix4iOS14.h"
    #import <objc/runtime.h>
    
    
    @interface UIPageControl ()
    
    
    @property (nonatomic, strong) UIImage *KN_currentImage;
    
    @property (nonatomic, strong, readonly) NSMutableDictionary<NSString *, UIImageView *> *KN_indicatorImages;
    
    
    @end
    
    @implementation UIPageControl (Fix4iOS14)
    
    
    static BOOL KN_shouldTreatImageAsTemplate(UIImageView *obj, SEL sel, id arg1) {
        
        UIPageControl *pageControl = (id)obj;
        while ((pageControl = (id)pageControl.superview)) {
            if ([pageControl isKindOfClass:[UIPageControl class]]) {
                if (pageControl.KN_currentImage) {
                    [pageControl.KN_indicatorImages setValue:obj forKeyPath:[[obj valueForKeyPath:@"_page"] description]];
                    return NO;
                } else {
                    break;
                }
            }
        }
        // 默认走系统的实现
        return ((BOOL (*)(UIView *, SEL, id))class_getMethodImplementation(obj.superclass, sel))(obj, sel, arg1);
    }
    
    + (void)load {
        if (@available(iOS 14, *)) {
            Class clazz = NSClassFromString(@"_UIPageIndicatorView");
            SEL sel = NSSelectorFromString(@"_shouldTreatImageAsTemplate:");
            class_addMethod(clazz, sel, (IMP)KN_shouldTreatImageAsTemplate, method_getTypeEncoding(class_getInstanceMethod(clazz, sel)));
            method_exchangeImplementations(class_getInstanceMethod(self, @selector(setCurrentPage:)),
                                           class_getInstanceMethod(self, @selector(KN_setCurrentPage:)));
            method_exchangeImplementations(class_getInstanceMethod(self, @selector(setNumberOfPages:)),
                                           class_getInstanceMethod(self, @selector(KN_setNumberOfPages:)));
        }
    }
    
    - (void)KN_setCurrentPage:(NSInteger)currentPage {
        [self KN_setCurrentPage:currentPage];
        [self KN_pageControlValueChange];
    }
    
    - (void)KN_setNumberOfPages:(NSInteger)numberOfPages {
        NSInteger currentPage = self.currentPage;
        [self KN_setNumberOfPages:numberOfPages];
        
        if (numberOfPages <= currentPage) {
            [self setIndicatorImage:self.KN_currentImage forPage:self.currentPage];
        }
        [self KN_refreshIndicatorTintColor];
    }
    
    - (void)setKN_currentImage:(UIImage *)KN_currentImage {
        objc_setAssociatedObject(self, @selector(KN_currentImage), KN_currentImage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (UIImage *)KN_currentImage {
        return objc_getAssociatedObject(self, _cmd);
    }
    
    - (NSMutableDictionary<NSString *, UIImageView *> *)KN_indicatorImages {
        if (!objc_getAssociatedObject(self, _cmd)) {
            objc_setAssociatedObject(self, _cmd, [NSMutableDictionary dictionary], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        }
        return objc_getAssociatedObject(self, _cmd);
    }
    
    /** 设置page control图片 */
    - (void)kn_SetCurrentImage:(UIImage *)currentImage pageImage:(UIImage *)pageImage {
        if (@available(iOS 14, *)) {
            self.KN_currentImage = currentImage;
            self.preferredIndicatorImage = pageImage;
            [self removeTarget:self
                        action:@selector(KN_pageControlValueChange)
              forControlEvents:UIControlEventValueChanged];
            [self addTarget:self
                     action:@selector(KN_pageControlValueChange)
           forControlEvents:UIControlEventValueChanged];
            dispatch_async(dispatch_get_main_queue(), ^{
                [self KN_refreshIndicatorTintColor];
            });
        } else {
            [self setValue:currentImage forKeyPath:@"_currentPageImage"];
            [self setValue:pageImage forKeyPath:@"_pageImage"];
        }
    }
    
    - (void)KN_pageControlValueChange {
        for (NSInteger i = 0; i < self.numberOfPages; i++) {
            if (i == self.currentPage) {
                if (@available(iOS 14.0, *)) {
                    [self setIndicatorImage:self.KN_currentImage forPage:self.currentPage];
                } else {
                    // Fallback on earlier versions
                }
            } else {
                if (@available(iOS 14.0, *)) {
                    [self setIndicatorImage:self.preferredIndicatorImage forPage:i];
                } else {
                    // Fallback on earlier versions
                }
            }
        }
    }
    
    - (void)KN_refreshIndicatorTintColor {
        for (NSInteger i = 0; i < self.numberOfPages; i++) {
            [self.KN_indicatorImages[@(i).description] tintColorDidChange];
        }
    }
    
    
    
    @end
    

    使用:

            UIPageControl *pageControl = [[UIPageControl alloc] init];
            pageControl.hidesForSinglePage = YES;
            if (@available(iOS 13.0, *)) {
                [pageControl kn_SetCurrentImage:[UIImage imageNamed:@"compose_keyboard_dot_selected"] pageImage:[UIImage imageNamed:@"compose_keyboard_dot_normal"]];
            } else {
                // Fallback on earlier versions
                [pageControl setValue:[UIImage imageWithName:@"compose_keyboard_dot_selected"] forKeyPath:@"_currentPageImage"];
                [pageControl setValue:[UIImage imageWithName:@"compose_keyboard_dot_normal"] forKeyPath:@"_pageImage"];
            }
            
            [self addSubview:pageControl];
            self.pageControl = pageControl;
    

    注意:如果count为空的时候,会闪退,所以在设置模型的时候会再做判断

    - (void)setEmotions:(NSArray *)emotions
    {
        _emotions = emotions;
        
        // 设置总页数
        NSInteger totalPages = (emotions.count + TFEmotionMaxCountPerPage - 1) / TFEmotionMaxCountPerPage;
        NSInteger currentGridViewCount = self.scrollView.subviews.count;
        if (totalPages <= 0) {
            self.pageControl.hidden = YES;
    //        self.pageControl.numberOfPages = totalPages;
        }else if (totalPages == 1){
            self.pageControl.hidesForSinglePage = YES;
            self.pageControl.numberOfPages = totalPages;
        }else{
            self.pageControl.hidden = NO;
            self.pageControl.numberOfPages = totalPages;
        }
        self.pageControl.currentPage = 0;
        
        [self setNeedsLayout];
        
        self.scrollView.contentOffset = CGPointZero;
    }
    

    跳转问题了

    这个应该是我的低级失误了,这个其实是给我自己提醒的,其实配置一直是没错

    [[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@"baidumap://"]]
    

    但是我手机没装百度地图,数组还是添加了。。。

    [self.mapArray addObject:@"百度地图"];
    

    到后来才发现是这里要这么添加,因为之前没有://


    image.png

    关于appdelegate里的window问题

    其实很多代码里写的还是

    UIApplication.sharedApplication.delegate.keyWindow
    

    事实上xcode的appdelegate只有window了,所以在有的第三方用起来的时候可能会闪退,所以解决要么是更新第三方,要么就只能用到闪退的位置的时候,全局断点来调试了

    使用百度地图的一点体会(地图定位,地图选点,选点的范围内的建筑名称,通过关键字搜索)算是给自己看的吧

    #import "MapAddressSelectViewController.h"
    #import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
    #import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
    #import <BMKLocationKit/BMKLocationManager.h>
    #import <BaiduMapAPI_Search/BMKSearchComponent.h>
    #import <BaiduMapAPI_Utils/BMKUtilsComponent.h>
    #import "MapListViewCell.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface MapAddressSelectViewController ()<BMKMapViewDelegate,BMKLocationManagerDelegate,BMKGeoCodeSearchDelegate,BMKPoiSearchDelegate,UITextFieldDelegate,UITableViewDataSource,UITableViewDelegate>
    @property (nonatomic, strong) BMKMapView *mapView;
    @property (nonatomic, strong) BMKLocationManager *locationManager; //定位对象
    @property (nonatomic, strong) BMKUserLocation *userLocation; //当前位置对象
    @property (nonatomic, strong) BMKGeoCodeSearch *search; //反地理编码搜索
    /** 获取方圆的地址数据的搜索 */
    @property (strong,nonatomic) BMKPoiSearch *poiSearch;
    
    /** 邮编 */
    @property (copy,nonatomic) NSString *areaCode;
    /** 获取区域名字 */
    @property (copy,nonatomic) NSString *cityName;
    /** 地址view */
    @property (weak,nonatomic) UIView *addressView;
    /** 地址搜索框 */
    @property (strong,nonatomic) UIButton *addrBtn;
    /** 表格 */
    @property (weak,nonatomic) UITableView *tableView;
    /// POI列表,成员是BMKPoiInfo
    @property (nonatomic, strong) NSMutableArray<BMKPoiInfo *> *poiInfos;
    /** 选中的poiInfo */
    @property (strong,nonatomic) BMKPoiInfo *selectedPoiInfo;
    /// 选中的地址数组
    @property (nonatomic, strong) NSMutableArray *selectArr;
    @end
    
    @implementation MapAddressSelectViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.navigationItem.title = @"选择地址";
        self.view.backgroundColor = [UIColor whiteColor];
        [self mapSetting];
        [self setupNav];
    
    
    //    //不显示定位图层
    //    _mapView.showsUserLocation = NO;
        UIView *addressView = [[UIView alloc]init];
        addressView.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:addressView];
        [addressView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.mas_equalTo(0);
            make.bottom.mas_equalTo(0);
            make.height.mas_equalTo(300);
        }];
        self.addressView = addressView;
    
        UITextField *addrTextF = [[UITextField alloc]init];
        addrTextF.textColor = [UIColor colorWithHexString:@"333333"];
        addrTextF.font = [UIFont hx_pingFangFontOfSize:14.0];
        addrTextF.layer.cornerRadius = 5;
        addrTextF.layer.masksToBounds = YES;
        addrTextF.backgroundColor = [UIColor colorWithHexString:@"f4f4f4"];
        addrTextF.leftView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 6, 0)];
        addrTextF.leftViewMode = UITextFieldViewModeAlways;
        [addrTextF addTarget:self action:@selector(textChanged:) forControlEvents:UIControlEventEditingChanged];
        addrTextF.returnKeyType = UIReturnKeySearch;
        addrTextF.delegate = self;
        [addressView addSubview:addrTextF];
        [addrTextF mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.mas_equalTo(15);
            make.right.mas_equalTo(-15);
            make.height.mas_equalTo(34);
        }];
        UIButton *addrBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        addrBtn.userInteractionEnabled = NO;
        [addrBtn setTitle:@"搜索地点" forState:UIControlStateNormal];
        addrBtn.titleLabel.font = [UIFont hx_pingFangFontOfSize:14.0];
        [addrBtn setTitleColor:[UIColor colorWithHexString:@"989898"] forState:UIControlStateNormal];
        [addrBtn setImage:[[UIImage imageNamed:@"addrSachi"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
        addrBtn.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);
        [addrTextF addSubview:addrBtn];
        self.addrBtn = addrBtn;
        [addrBtn mas_makeConstraints:^(MASConstraintMaker *make) {
            make.edges.mas_equalTo(addrTextF);
        }];
    
        UITableView *tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain];
        tableView.backgroundColor = [UIColor whiteColor];
        tableView.dataSource = self;
        tableView.delegate = self;
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        [addressView addSubview:tableView];
        [tableView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.right.mas_equalTo(0);
            make.top.mas_equalTo(addrTextF.mas_bottom).offset(15);
            make.bottom.mas_equalTo(0);
        }];
        [tableView registerNib:[UINib nibWithNibName:@"MapListViewCell" bundle:nil] forCellReuseIdentifier:@"MapListViewCell"];
        self.tableView = tableView;
    
        UIView *locaView = [[UIView alloc]init];
        locaView.backgroundColor = [UIColor clearColor];
        locaView.userInteractionEnabled = YES;
        [self.view addSubview:locaView];
        [locaView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.mas_equalTo(-10);
            make.bottom.mas_equalTo(addressView.mas_top).offset(10);
            make.width.height.mas_equalTo(60);
        }];
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(locationTap)];
        [locaView addGestureRecognizer:tap];
        UIImageView *locaV = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"addLoca"]];
        [locaView addSubview:locaV];
        [locaV mas_makeConstraints:^(MASConstraintMaker *make) {
            make.bottom.right.mas_equalTo(0);
            make.width.height.mas_equalTo(40);
        }];
    }
    
    -(void)mapSetting{
        self.mapView = [[BMKMapView alloc]initWithFrame:self.view.bounds];
        self.mapView.delegate = self;
        // 将当前地图显示缩放等级设置为21级
        [_mapView setZoomLevel:21];
    
        //开启定位服务
        [self.locationManager startUpdatingLocation];
        [self.locationManager startUpdatingHeading];
        //显示定位图层
        _mapView.showsUserLocation = YES;
        //设置定位模式为定位跟随模式
    //    _mapView.userTrackingMode = BMKUserTrackingModeFollow;
        [self.view addSubview:self.mapView];
    
        self.search = [[BMKGeoCodeSearch alloc]init];
        self.search.delegate = self;
    
        self.poiSearch = [[BMKPoiSearch alloc]init];
        self.poiSearch.delegate = self;
    }
    
    -(void)setupNav{
        UIView *nav = [[UIView alloc]init];
        nav.backgroundColor = [UIColor clearColor];
        [self.view addSubview:nav];
        [nav mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(XYStatusBarH);
            make.left.right.mas_equalTo(0);
            make.height.mas_equalTo(XYNavBarH);
        }];
    
        UIView *leftV = [[UIView alloc]init];
        leftV.backgroundColor = [UIColor clearColor];
        [nav addSubview:leftV];
        [leftV mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(15);
            make.top.bottom.mas_equalTo(0);
            make.width.mas_equalTo(45);
        }];
        UITapGestureRecognizer *cancelTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(cancelClick)];
        [leftV addGestureRecognizer:cancelTap];
    
        UILabel *cancelLb = [[UILabel alloc]init];
        cancelLb.text = @"取消";
        cancelLb.textColor = [UIColor colorWithHexString:@"333333"];
        cancelLb.font = [UIFont hx_pingFangFontOfSize:14.0];
        [leftV addSubview:cancelLb];
        [cancelLb mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.mas_equalTo(0);
            make.centerY.mas_equalTo(leftV.mas_centerY);
        }];
    
        UIButton *saveBtn = [UIButton buttonWithType:(UIButtonTypeCustom)];
        [saveBtn setTitle:@"确定" forState:(UIControlStateNormal)];
        saveBtn.titleLabel.font = [UIFont fontWithName:@"PingFangSC-Regular" size:14.0];
        [saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        saveBtn.backgroundColor = [UIColor colorWithHexString:@"07c05f"];
        saveBtn.layer.cornerRadius = 3;
        saveBtn.layer.masksToBounds = YES;
        [nav addSubview:saveBtn];
        [saveBtn mas_makeConstraints:^(MASConstraintMaker *make) {
            make.right.mas_equalTo(-15);
            make.width.mas_equalTo(50);
            make.height.mas_equalTo(25);
            make.centerY.mas_equalTo(leftV.mas_centerY);
        }];
        xy_weakify(self);
        [saveBtn bk_addEventHandler:^(id  _Nonnull sender) {
            ZRLog(@"经纬度%f  %f",weakself.selectedPoiInfo.pt.latitude,weakself.selectedPoiInfo.pt.longitude);
            ZRLog(@"地址%@  %@",weakself.selectedPoiInfo.name,weakself.selectedPoiInfo.address);
            ZRLog(@"%@",weakself.areaCode);
            if (weakself.addressSelectBlock) {
                weakself.addressSelectBlock(weakself.selectedPoiInfo.pt, weakself.selectedPoiInfo.address, weakself.selectedPoiInfo.name);
            }
            if (weakself.ruleAddressSelectBlock) {
                weakself.ruleAddressSelectBlock(weakself.selectedPoiInfo.pt, weakself.selectedPoiInfo.address, weakself.areaCode,weakself.selectedPoiInfo.name);
            }
            [weakself.navigationController popViewControllerAnimated:YES];
        } forControlEvents:UIControlEventTouchUpInside];
    }
    
    -(void)cancelClick{
        [self.navigationController popViewControllerAnimated:YES];
    }
    
    -(void)textChanged:(UITextField *)textField{
        if (textField.text.length > 0) {
            self.addrBtn.hidden = YES;
        }else{
            self.addrBtn.hidden = NO;
        }
    
        //初始化请求参数类BMKCitySearchOption的实例
        BMKPOICitySearchOption *cityOption = [[BMKPOICitySearchOption alloc] init];
        //检索关键字,必选。举例:小吃
        cityOption.keyword = textField.text;
        //区域名称(市或区的名字,如北京市,海淀区),最长不超过25个字符,必选
        cityOption.city = self.cityName;
        //检索分类,可选,与keyword字段组合进行检索,多个分类以","分隔。举例:美食,烧烤,酒店
    //    cityOption.tags = @[@"美食",@"烧烤"];
        //区域数据返回限制,可选,为YES时,仅返回city对应区域内数据
        cityOption.isCityLimit = YES;
        //POI检索结果详细程度
        //cityOption.scope = BMK_POI_SCOPE_BASIC_INFORMATION;
        //检索过滤条件,scope字段为BMK_POI_SCOPE_DETAIL_INFORMATION时,filter字段才有效
        //cityOption.filter = filter;
        //分页页码,默认为0,0代表第一页,1代表第二页,以此类推
        cityOption.pageIndex = 0;
        //单次召回POI数量,默认为10条记录,最大返回20条
        cityOption.pageSize = 10;
    
        BOOL flag = [self.poiSearch poiSearchInCity:cityOption];
        if (flag) {
            ZRLog(@"POI周边检索成功");
        }else{
            ZRLog(@"POI周边检索失败");
        }
    }
    
    -(void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        self.navigationController.navigationBar.hidden = YES;
        [_mapView viewWillAppear];
    }
    
    -(void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        self.navigationController.navigationBar.hidden = NO;
        [_mapView viewWillDisappear];
    }
    
    -(void)locationTap{
        [self.mapView removeAnnotations:self.mapView.annotations];
        //开启定位服务
        [self.locationManager startUpdatingLocation];
        [self.locationManager startUpdatingHeading];
        //设置定位模式为定位跟随模式
    //    self.mapView.userTrackingMode = BMKUserTrackingModeFollow;
    }
    
    #pragma mark - UITextFieldDelegate
    - (BOOL)textFieldShouldReturn:(UITextField *)textField{
        [self.view endEditing:YES];
        [self textChanged:textField];
        return YES;
    }
    #pragma mark - BMKLocationManagerDelegate
    /**
     @brief 当定位发生错误时,会调用代理的此方法
     @param manager 定位 BMKLocationManager 类
     @param error 返回的错误,参考 CLError
     */
    - (void)BMKLocationManager:(BMKLocationManager * _Nonnull)manager didFailWithError:(NSError * _Nullable)error {
        NSLog(@"定位失败");
    }
    
    /**
     @brief 该方法为BMKLocationManager提供设备朝向的回调方法
     @param manager 提供该定位结果的BMKLocationManager类的实例
     @param heading 设备的朝向结果
     */
    - (void)BMKLocationManager:(BMKLocationManager *)manager didUpdateHeading:(CLHeading *)heading {
        if (!heading) {
            return;
        }
        ZRLog(@"用户方向更新:%f",self.userLocation.location.coordinate.latitude);
        self.userLocation.heading = heading;
        [_mapView updateLocationData:self.userLocation];
    }
    
    /**
     @brief 连续定位回调函数
     @param manager 定位 BMKLocationManager 类
     @param location 定位结果,参考BMKLocation
     @param error 错误信息。
     */
    - (void)BMKLocationManager:(BMKLocationManager *)manager didUpdateLocation:(BMKLocation *)location orError:(NSError *)error {
        if (error) {
            NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
        }
        if (!location) {
            return;
        }
    
        self.userLocation.location = location.location;
    
        //实现该方法,否则定位图标不出现
        [_mapView updateLocationData:self.userLocation];
    
        //设置当前地图的中心点
        self.mapView.centerCoordinate = self.userLocation.location.coordinate;
        // 这里可以获取地理位置的经纬度
        BMKReverseGeoCodeSearchOption *reverseGeoCodeOption = [[BMKReverseGeoCodeSearchOption alloc]init];
        reverseGeoCodeOption.location = CLLocationCoordinate2DMake(self.userLocation.location.coordinate.latitude, self.userLocation.location.coordinate.longitude);
        // 是否访问最新版行政区划数据(仅对中国数据生效)
        reverseGeoCodeOption.isLatestAdmin = YES;
        BOOL flag = [self.search reverseGeoCode: reverseGeoCodeOption];
        if (flag) {
            NSLog(@"逆geo检索发送成功");
        }  else  {
            NSLog(@"逆geo检索发送失败");
        }
    
        //定位之后马上关闭定位服务
        [self.locationManager stopUpdatingLocation];
        [self.locationManager stopUpdatingHeading];
    }
    
    #pragma mark - BMKGeoCodeSearchDelegate
    /**
     反向地理编码检索结果回调
    
     @param searcher 检索对象
     @param result 反向地理编码检索结果
     @param error 错误码,@see BMKCloudErrorCode
     */
    - (void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeSearchResult *)result errorCode:(BMKSearchErrorCode)error {
        if (error == BMK_SEARCH_NO_ERROR) {
            //在此处理正常结果
            ZRLog(@"%f",result.location.latitude);
            self.areaCode = result.addressDetail.adCode;
            // 这个是定位之后获取的一个地址名字,方便搜索的时候用的
            self.cityName = result.addressDetail.streetName;
            [self.poiInfos removeAllObjects];
            [self.poiInfos addObjectsFromArray:result.poiList];
            [self.selectArr removeAllObjects];
            for (int i = 0;i < self.poiInfos.count;i ++) {
                BMKPoiInfo *point = self.poiInfos[i];
    
                // 由于不能存逻辑值,而且不能用百度的模型,那么存字符串了
                NSString *select = @"未选中";
                if (i == 0) { // 默认第一个选中
                    self.selectedPoiInfo = point;
                    select = @"选中";
                }
                [self.selectArr addObject:select];
            }
            [self.tableView reloadData];
        } else {
            NSLog(@"检索失败");
        }
    }
    
    #pragma mark - BMKMapViewDelegate
    /**
     根据anntation生成对应的annotationView
    
     @param mapView 地图View
     @param annotation 指定的标注
     @return 生成的标注View
     */
    - (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation {
        /**
         根据指定标识查找一个可被复用的标注,用此方法来代替新创建一个标注,返回可被复用的标注
         */
        BMKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"annotationViewIdentifier"];
        if (!annotationView) {
            /**
             初始化并返回一个annotationView
    
             @param annotation 关联的annotation对象
             @param reuseIdentifier 如果要重用view,传入一个字符串,否则设为nil,建议重用view
             @return 初始化成功则返回annotationView,否则返回nil
             */
            annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotationViewIdentifier"];
        }
        //annotationView关联的annotation
        annotationView.annotation = annotation;
        return annotationView;
    }
    
    /**
     *点中地图空白处会回调此接口(这里可以用作添加大头针)
     *@param mapView 地图View
     *@param coordinate 空白处坐标点的经纬度
     */
    - (void)mapView:(BMKMapView *)mapView onClickedMapBlank:(CLLocationCoordinate2D)coordinate{
        [self.mapView removeAnnotations:self.mapView.annotations];
        //初始化标注类BMKPointAnnotation的实例
        BMKPointAnnotation *annotation = [[BMKPointAnnotation alloc]init];
        //设置标注的经纬度坐标
        annotation.coordinate = coordinate;
        /**
    
         当前地图添加标注,需要实现BMKMapViewDelegate的-mapView:viewForAnnotation:方法
         来生成标注对应的View
         @param annotation 要添加的标注
         */
        [self.mapView addAnnotation:annotation];
        //设置当前地图的中心点
        self.mapView.centerCoordinate = annotation.coordinate;
    
        // 这里可以获取地理位置的经纬度
        BMKReverseGeoCodeSearchOption *reverseGeoCodeOption = [[BMKReverseGeoCodeSearchOption alloc]init];
        reverseGeoCodeOption.location = coordinate;
        // 是否访问最新版行政区划数据(仅对中国数据生效)
        reverseGeoCodeOption.isLatestAdmin = YES;
        BOOL flag = [self.search reverseGeoCode: reverseGeoCodeOption];
        if (flag) {
            NSLog(@"逆geo检索发送成功");
        }  else  {
            NSLog(@"逆geo检索发送失败");
        }
    }
    #pragma mark - BMKPoiSearchDelegate
    /**
     *返回POI搜索结果
     *@param searcher 搜索对象
     *@param poiResult 搜索结果列表
     *@param errorCode 错误号,@see BMKSearchErrorCode
     */
    -(void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPOISearchResult *)poiResult errorCode:(BMKSearchErrorCode)errorCode{
        //BMKSearchErrorCode错误码,BMK_SEARCH_NO_ERROR:检索结果正常返回
        if (errorCode == BMK_SEARCH_NO_ERROR) {
            //在此处理正常结果
            ZRLog(@"检索结果返回成功:%@",poiResult.poiInfoList);
            [self.poiInfos removeAllObjects];
            [self.poiInfos addObjectsFromArray:poiResult.poiInfoList];
            [self.selectArr removeAllObjects];
            for (int i = 0;i < self.poiInfos.count;i ++) {
                BMKPoiInfo *point = self.poiInfos[i];
                // 这个是定位之后获取的一个地址名字,方便搜索的时候用的
                self.cityName = point.address;
    
                // 计算距离
                if (point.distance == 0) {
                    BMKMapPoint point1 = BMKMapPointForCoordinate(point.pt);
                    BMKMapPoint point2 = BMKMapPointForCoordinate(self.userLocation.location.coordinate);
                    CLLocationDistance distance = BMKMetersBetweenMapPoints(point1,point2);
                    point.distance = distance;
                }
                // 由于不能存逻辑值,而且不能用百度的模型,那么存字符串了
                NSString *select = @"未选中";
                if (i == 0) { // 默认第一个选中
                    self.selectedPoiInfo = point;
                    select = @"选中";
    
                    // 移动到地图选定的地址
                    [self.mapView removeAnnotations:self.mapView.annotations];
                    //初始化标注类BMKPointAnnotation的实例
                    BMKPointAnnotation *annotation = [[BMKPointAnnotation alloc]init];
                    //设置标注的经纬度坐标
                    annotation.coordinate = point.pt;
                    /**
    
                     当前地图添加标注,需要实现BMKMapViewDelegate的-mapView:viewForAnnotation:方法
                     来生成标注对应的View
                     @param annotation 要添加的标注
                     */
                    [self.mapView addAnnotation:annotation];
                    //设置当前地图的中心点
                    self.mapView.centerCoordinate = annotation.coordinate;
    
                    // 由于搜索到的获取不到邮政编码,所以用系统框架,获取邮政编码
                    //根据经纬度获取省份城市
                    CLGeocoder *clGeoCoder = [[CLGeocoder alloc] init];
                    CLLocation *newLocation = [[CLLocation alloc]initWithLatitude:point.pt.latitude longitude:point.pt.longitude];
                    [clGeoCoder reverseGeocodeLocation:newLocation completionHandler: ^(NSArray *placemarks,NSError *error) {
                            for (CLPlacemark *placeMark in placemarks)
                            {
                              self.areaCode = placeMark.postalCode;
                            }
                    }];
                }
                [self.selectArr addObject:select];
            }
            [self.tableView reloadData];
        }
        else if (errorCode == BMK_SEARCH_AMBIGUOUS_KEYWORD) {
            ZRLog(@"检索词有歧义");
        } else {
            ZRLog(@"其他检索结果错误码相关处理");
        }
    }
    #pragma mark - UITableViewDataSource,UITableViewDelegate
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return self.poiInfos.count;
    }
    
    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        MapListViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MapListViewCell"];
        cell.poiInfo = self.poiInfos[indexPath.row];
        cell.addrSelect = self.selectArr[indexPath.row];
        if (indexPath.row == self.poiInfos.count) {
            cell.showLine = NO;
        }else{
            cell.showLine = YES;
        }
        return cell;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        return 76;
    }
    
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
        BMKPoiInfo *poiInfo = self.poiInfos[indexPath.row];
        self.selectedPoiInfo = poiInfo;
        for (int i = 0; i < self.selectArr.count; i ++) {
            [self.selectArr replaceObjectAtIndex:i withObject:@"未选中"];
        }
        [self.selectArr replaceObjectAtIndex:indexPath.row withObject:@"选中"];
    
        // 移动到地图选定的地址
        [self.mapView removeAnnotations:self.mapView.annotations];
        //初始化标注类BMKPointAnnotation的实例
        BMKPointAnnotation *annotation = [[BMKPointAnnotation alloc]init];
        //设置标注的经纬度坐标
        annotation.coordinate = poiInfo.pt;
        /**
    
         当前地图添加标注,需要实现BMKMapViewDelegate的-mapView:viewForAnnotation:方法
         来生成标注对应的View
         @param annotation 要添加的标注
         */
        [self.mapView addAnnotation:annotation];
        //设置当前地图的中心点
        self.mapView.centerCoordinate = annotation.coordinate;
    
        //根据经纬度获取省份城市
        CLGeocoder *clGeoCoder = [[CLGeocoder alloc] init];
        CLLocation *newLocation = [[CLLocation alloc]initWithLatitude:self.selectedPoiInfo.pt.latitude longitude:self.selectedPoiInfo.pt.longitude];
        [clGeoCoder reverseGeocodeLocation:newLocation completionHandler: ^(NSArray *placemarks,NSError *error) {
                for (CLPlacemark *placeMark in placemarks)
                {
                  self.areaCode = placeMark.postalCode;
                }
        }];
    
        [self.tableView reloadData];
    }
    
    #pragma mark - Lazy loading
    -(NSMutableArray<BMKPoiInfo *> *)poiInfos{
        if (!_poiInfos) {
            _poiInfos = [[NSMutableArray alloc]init];
        }
        return _poiInfos;
    }
    
    -(NSMutableArray *)selectArr{
        if (!_selectArr) {
            _selectArr = [[NSMutableArray alloc]init];
        }
        return _selectArr;
    }
    - (BMKLocationManager *)locationManager {
        if (!_locationManager) {
            //初始化BMKLocationManager类的实例
            _locationManager = [[BMKLocationManager alloc] init];
            //设置定位管理类实例的代理
            _locationManager.delegate = self;
            //设定定位坐标系类型,默认为 BMKLocationCoordinateTypeGCJ02
            _locationManager.coordinateType = BMKLocationCoordinateTypeBMK09LL;
            //设定定位精度,默认为 kCLLocationAccuracyBest
            _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
            //设定定位类型,默认为 CLActivityTypeAutomotiveNavigation
            _locationManager.activityType = CLActivityTypeAutomotiveNavigation;
            //指定定位是否会被系统自动暂停,默认为NO
            _locationManager.pausesLocationUpdatesAutomatically = NO;
            /**
             是否允许后台定位,默认为NO。只在iOS 9.0及之后起作用。
             设置为YES的时候必须保证 Background Modes 中的 Location updates 处于选中状态,否则会抛出异常。
             由于iOS系统限制,需要在定位未开始之前或定位停止之后,修改该属性的值才会有效果。
             */
            _locationManager.allowsBackgroundLocationUpdates = NO;
            /**
             指定单次定位超时时间,默认为10s,最小值是2s。注意单次定位请求前设置。
             注意: 单次定位超时时间从确定了定位权限(非kCLAuthorizationStatusNotDetermined状态)
             后开始计算。
             */
            _locationManager.locationTimeout = 10;
        }
        return _locationManager;
    }
    
    - (BMKUserLocation *)userLocation {
        if (!_userLocation) {
            //初始化BMKUserLocation类的实例
            _userLocation = [[BMKUserLocation alloc] init];
        }
        return _userLocation;
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:最近接触的技术点二

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