最近接触的技术点二

2020-12-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
上一篇 下一篇

猜你喜欢

热点阅读