cdts/xdts-ios 3/TreeHole/Code/Gategory/BRPickerView/AddressPickerView/BRAddressPickerView.m

559 lines
22 KiB
Mathematica
Raw Normal View History

2023-07-27 09:20:00 +08:00
//
// BRAddressPickerView.m
// BRPickerViewDemo
//
// Created by renbo on 2017/8/11.
// Copyright © 2017 irenb. All rights reserved.
//
// https://github.com/91renb/BRPickerView
#import "BRAddressPickerView.h"
#import "NSBundle+BRPickerView.h"
@interface BRAddressPickerView ()<UIPickerViewDataSource, UIPickerViewDelegate>
//
@property (nonatomic, strong) UIPickerView *pickerView;
//
@property(nonatomic, copy) NSArray *provinceModelArr;
//
@property(nonatomic, copy) NSArray *cityModelArr;
//
@property(nonatomic, copy) NSArray *areaModelArr;
//
@property(nonatomic, strong) BRProvinceModel *selectProvinceModel;
//
@property(nonatomic, strong) BRCityModel *selectCityModel;
//
@property(nonatomic, strong) BRAreaModel *selectAreaModel;
//
@property(nonatomic, assign) NSInteger provinceIndex;
//
@property(nonatomic, assign) NSInteger cityIndex;
//
@property(nonatomic, assign) NSInteger areaIndex;
@property (nonatomic, copy) NSArray <NSString *>* mSelectValues;
@end
@implementation BRAddressPickerView
#pragma mark - 1.
+ (void)showAddressPickerWithSelectIndexs:(NSArray <NSNumber *>*)selectIndexs
resultBlock:(BRAddressResultBlock)resultBlock {
[self showAddressPickerWithMode:BRAddressPickerModeArea dataSource:nil selectIndexs:selectIndexs isAutoSelect:NO resultBlock:resultBlock];
}
#pragma mark - 2.
+ (void)showAddressPickerWithMode:(BRAddressPickerMode)mode
selectIndexs:(NSArray <NSNumber *>*)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(BRAddressResultBlock)resultBlock {
[self showAddressPickerWithMode:mode dataSource:nil selectIndexs:selectIndexs isAutoSelect:isAutoSelect resultBlock:resultBlock];
}
#pragma mark - 3.
+ (void)showAddressPickerWithMode:(BRAddressPickerMode)mode
dataSource:(NSArray *)dataSource
selectIndexs:(NSArray <NSNumber *>*)selectIndexs
isAutoSelect:(BOOL)isAutoSelect
resultBlock:(BRAddressResultBlock)resultBlock {
//
BRAddressPickerView *addressPickerView = [[BRAddressPickerView alloc] initWithPickerMode:mode];
addressPickerView.dataSourceArr = dataSource;
addressPickerView.selectIndexs = selectIndexs;
addressPickerView.isAutoSelect = isAutoSelect;
addressPickerView.resultBlock = resultBlock;
//
[addressPickerView show];
}
#pragma mark -
- (instancetype)initWithPickerMode:(BRAddressPickerMode)pickerMode {
if (self = [super init]) {
self.pickerMode = pickerMode;
}
return self;
}
#pragma mark -
- (void)handlerPickerData {
if (self.dataSourceArr && self.dataSourceArr.count > 0) {
id item = [self.dataSourceArr firstObject];
//
if ([item isKindOfClass:[BRProvinceModel class]]) {
self.provinceModelArr = self.dataSourceArr;
} else {
self.provinceModelArr = [self getProvinceModelArr:self.dataSourceArr];
}
} else {
// 使
NSArray *dataSource = [self br_addressJsonArray];
if (!dataSource || dataSource.count == 0) {
return;
}
self.dataSourceArr = dataSource;
self.provinceModelArr = [self getProvinceModelArr:self.dataSourceArr];
}
//
[self handlerDefaultSelectValue];
}
#pragma mark - JSON
- (NSArray *)br_addressJsonArray {
static NSArray *cityArray = nil;
if (!cityArray) {
// BRAddressPickerView.bundle
NSBundle *containnerBundle = [NSBundle bundleForClass:[BRAddressPickerView class]];
NSString *bundlePath = [containnerBundle pathForResource:@"BRAddressPickerView" ofType:@"bundle"];
NSBundle *addressPickerBundle = [NSBundle bundleWithPath:bundlePath];
// bundleJSON
NSString *filePath = [addressPickerBundle pathForResource:@"BRCity" ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:filePath];
cityArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
}
return cityArray;
}
#pragma mark -
- (NSArray <BRProvinceModel *>*)getProvinceModelArr:(NSArray *)dataSourceArr {
NSMutableArray *tempArr1 = [NSMutableArray array];
for (NSDictionary *proviceDic in dataSourceArr) {
BRProvinceModel *proviceModel = [[BRProvinceModel alloc]init];
proviceModel.code = [proviceDic objectForKey:@"code"];
proviceModel.name = [proviceDic objectForKey:@"name"];
proviceModel.index = [dataSourceArr indexOfObject:proviceDic];
NSArray *cityList = [proviceDic.allKeys containsObject:@"cityList"] ? [proviceDic objectForKey:@"cityList"] : [proviceDic objectForKey:@"citylist"];
NSMutableArray *tempArr2 = [NSMutableArray array];
for (NSDictionary *cityDic in cityList) {
BRCityModel *cityModel = [[BRCityModel alloc]init];
cityModel.code = [cityDic objectForKey:@"code"];
cityModel.name = [cityDic objectForKey:@"name"];
cityModel.index = [cityList indexOfObject:cityDic];
NSArray *areaList = [cityDic.allKeys containsObject:@"areaList"] ? [cityDic objectForKey:@"areaList"] : [cityDic objectForKey:@"arealist"];
NSMutableArray *tempArr3 = [NSMutableArray array];
for (NSDictionary *areaDic in areaList) {
BRAreaModel *areaModel = [[BRAreaModel alloc]init];
areaModel.code = [areaDic objectForKey:@"code"];
areaModel.name = [areaDic objectForKey:@"name"];
areaModel.index = [areaList indexOfObject:areaDic];
[tempArr3 addObject:areaModel];
}
cityModel.arealist = [tempArr3 copy];
[tempArr2 addObject:cityModel];
}
proviceModel.citylist = [tempArr2 copy];
[tempArr1 addObject:proviceModel];
}
return [tempArr1 copy];
}
#pragma mark -
- (void)handlerDefaultSelectValue {
__block NSString *selectProvinceName = nil;
__block NSString *selectCityName = nil;
__block NSString *selectAreaName = nil;
if (self.mSelectValues.count > 0) {
selectProvinceName = self.mSelectValues.count > 0 ? self.mSelectValues[0] : nil;
selectCityName = self.mSelectValues.count > 1 ? self.mSelectValues[1] : nil;
selectAreaName = self.mSelectValues.count > 2 ? self.mSelectValues[2] : nil;
}
__weak typeof(self) weakSelf = self;
if (self.pickerMode == BRAddressPickerModeProvince || self.pickerMode == BRAddressPickerModeCity || self.pickerMode == BRAddressPickerModeArea) {
if (self.selectIndexs.count > 0) {
NSInteger provinceIndex = [self.selectIndexs[0] integerValue];
self.provinceIndex = (provinceIndex > 0 && provinceIndex < self.provinceModelArr.count) ? provinceIndex : 0;
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
} else {
self.provinceIndex = 0;
self.selectProvinceModel = self.provinceModelArr.count > 0 ? self.provinceModelArr[0] : nil;
[self.provinceModelArr enumerateObjectsUsingBlock:^(BRProvinceModel * _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
if (selectProvinceName && [model.name isEqualToString:selectProvinceName]) {
weakSelf.provinceIndex = idx;
weakSelf.selectProvinceModel = model;
*stop = YES;
}
}];
}
}
if (self.pickerMode == BRAddressPickerModeCity || self.pickerMode == BRAddressPickerModeArea) {
self.cityModelArr = [self getCityModelArray:self.provinceIndex];
if (self.selectIndexs.count > 0) {
NSInteger cityIndex = self.selectIndexs.count > 1 ? [self.selectIndexs[1] integerValue] : 0;
self.cityIndex = (cityIndex > 0 && cityIndex < self.cityModelArr.count) ? cityIndex : 0;
self.selectCityModel = self.cityModelArr.count > self.cityIndex ? self.cityModelArr[self.cityIndex] : nil;
} else {
self.cityIndex = 0;
self.selectCityModel = self.cityModelArr.count > 0 ? self.cityModelArr[0] : nil;
[self.cityModelArr enumerateObjectsUsingBlock:^(BRCityModel * _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
if (selectCityName && [model.name isEqualToString:selectCityName]) {
weakSelf.cityIndex = idx;
weakSelf.selectCityModel = model;
*stop = YES;
}
}];
}
}
if (self.pickerMode == BRAddressPickerModeArea) {
self.areaModelArr = [self getAreaModelArray:self.provinceIndex cityIndex:self.cityIndex];
if (self.selectIndexs.count > 0) {
NSInteger areaIndex = self.selectIndexs.count > 2 ? [self.selectIndexs[2] integerValue] : 0;
self.areaIndex = (areaIndex > 0 && areaIndex < self.areaModelArr.count) ? areaIndex : 0;
self.selectAreaModel = self.areaModelArr.count > self.areaIndex ? self.areaModelArr[self.areaIndex] : nil;
} else {
self.areaIndex = 0;
self.selectAreaModel = self.areaModelArr.count > 0 ? self.areaModelArr[0] : nil;
[self.areaModelArr enumerateObjectsUsingBlock:^(BRAreaModel * _Nonnull model, NSUInteger idx, BOOL * _Nonnull stop) {
if (selectAreaName && [model.name isEqualToString:selectAreaName]) {
weakSelf.areaIndex = idx;
weakSelf.selectAreaModel = model;
*stop = YES;
}
}];
}
}
}
//
- (NSArray *)getCityModelArray:(NSInteger)provinceIndex {
BRProvinceModel *provinceModel = self.provinceModelArr[provinceIndex];
//
return provinceModel.citylist;
}
//
- (NSArray *)getAreaModelArray:(NSInteger)provinceIndex cityIndex:(NSInteger)cityIndex {
BRProvinceModel *provinceModel = self.provinceModelArr[provinceIndex];
if (provinceModel.citylist && provinceModel.citylist.count > 0) {
BRCityModel *cityModel = provinceModel.citylist[cityIndex];
//
return cityModel.arealist;
} else {
return nil;
}
}
#pragma mark -
- (UIPickerView *)pickerView {
if (!_pickerView) {
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
_pickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0, self.pickerStyle.titleBarHeight + pickerHeaderViewHeight, self.keyView.bounds.size.width, self.pickerStyle.pickerHeight)];
_pickerView.backgroundColor = self.pickerStyle.pickerColor;
_pickerView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
_pickerView.dataSource = self;
_pickerView.delegate = self;
}
return _pickerView;
}
#pragma mark - UIPickerViewDataSource
// 1. pickerView
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
switch (self.pickerMode) {
case BRAddressPickerModeProvince:
return 1;
break;
case BRAddressPickerModeCity:
return 2;
break;
case BRAddressPickerModeArea:
return 3;
break;
default:
break;
}
}
// 2. pickerView
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component == 0) {
//
return self.provinceModelArr.count;
}
if (component == 1) {
//
return self.cityModelArr.count;
}
if (component == 2) {
//
return self.areaModelArr.count;
}
return 0;
}
#pragma mark - UIPickerViewDelegate
// 3. pickerView
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(nullable UIView *)view {
// 1. row
UILabel *label = (UILabel *)view;
if (!label) {
label = [[UILabel alloc]init];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = self.pickerStyle.pickerTextFont;
label.textColor = self.pickerStyle.pickerTextColor;
//
label.adjustsFontSizeToFitWidth = YES;
//
label.minimumScaleFactor = 0.5f;
}
if (component == 0) {
BRProvinceModel *model = self.provinceModelArr[row];
label.text = model.name;
} else if (component == 1) {
BRCityModel *model = self.cityModelArr[row];
label.text = model.name;
} else if (component == 2) {
BRAreaModel *model = self.areaModelArr[row];
label.text = model.name;
}
// 2.
[self.pickerStyle setupPickerSelectRowStyle:pickerView titleForRow:row forComponent:component];
return label;
}
// 4. pickerView
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == 0) { //
//
self.provinceIndex = row;
switch (self.pickerMode) {
case BRAddressPickerModeProvince:
{
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
self.selectCityModel = nil;
self.selectAreaModel = nil;
}
break;
case BRAddressPickerModeCity:
{
self.cityModelArr = [self getCityModelArray:self.provinceIndex];
[self.pickerView reloadComponent:1];
[self.pickerView selectRow:0 inComponent:1 animated:YES];
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
self.selectCityModel = self.cityModelArr.count > 0 ? self.cityModelArr[0] : nil;
self.selectAreaModel = nil;
}
break;
case BRAddressPickerModeArea:
{
self.cityModelArr = [self getCityModelArray:self.provinceIndex];
self.areaModelArr = [self getAreaModelArray:self.provinceIndex cityIndex:0];
[self.pickerView reloadComponent:1];
[self.pickerView selectRow:0 inComponent:1 animated:YES];
[self.pickerView reloadComponent:2];
[self.pickerView selectRow:0 inComponent:2 animated:YES];
self.selectProvinceModel = self.provinceModelArr.count > self.provinceIndex ? self.provinceModelArr[self.provinceIndex] : nil;
self.selectCityModel = self.cityModelArr.count > 0 ? self.cityModelArr[0] : nil;
self.selectAreaModel = self.areaModelArr.count > 0 ? self.areaModelArr[0] : nil;
}
break;
default:
break;
}
}
if (component == 1) { //
//
self.cityIndex = row;
switch (self.pickerMode) {
case BRAddressPickerModeCity:
{
self.selectCityModel = self.cityModelArr.count > self.cityIndex ? self.cityModelArr[self.cityIndex] : nil;
self.selectAreaModel = nil;
}
break;
case BRAddressPickerModeArea:
{
self.areaModelArr = [self getAreaModelArray:self.provinceIndex cityIndex:self.cityIndex];
[self.pickerView reloadComponent:2];
[self.pickerView selectRow:0 inComponent:2 animated:YES];
self.selectCityModel = self.cityModelArr.count > self.cityIndex ? self.cityModelArr[self.cityIndex] : nil;
self.selectAreaModel = self.areaModelArr.count > 0 ? self.areaModelArr[0] : nil;
}
break;
default:
break;
}
}
if (component == 2) { //
//
self.areaIndex = row;
if (self.pickerMode == BRAddressPickerModeArea) {
self.selectAreaModel = self.areaModelArr.count > self.areaIndex ? self.areaModelArr[self.areaIndex] : nil;
}
}
// changeBlock
if (self.changeBlock) {
self.changeBlock(self.selectProvinceModel, self.selectCityModel, self.selectAreaModel);
}
// resultBlock
if (self.isAutoSelect) {
if (self.resultBlock) {
self.resultBlock(self.selectProvinceModel, self.selectCityModel, self.selectAreaModel);
}
}
}
//
- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
return self.pickerStyle.rowHeight;
}
#pragma mark -
- (void)reloadData {
// 1.
[self handlerPickerData];
// 2.
[self.pickerView reloadAllComponents];
// 3.
if (self.pickerMode == BRAddressPickerModeProvince) {
[self.pickerView selectRow:self.provinceIndex inComponent:0 animated:YES];
} else if (self.pickerMode == BRAddressPickerModeCity) {
[self.pickerView selectRow:self.provinceIndex inComponent:0 animated:YES];
[self.pickerView selectRow:self.cityIndex inComponent:1 animated:YES];
} else if (self.pickerMode == BRAddressPickerModeArea) {
[self.pickerView selectRow:self.provinceIndex inComponent:0 animated:YES];
[self.pickerView selectRow:self.cityIndex inComponent:1 animated:YES];
[self.pickerView selectRow:self.areaIndex inComponent:2 animated:YES];
}
}
- (void)addPickerToView:(UIView *)view {
// 1.
if (view) {
// view view 使
[view setNeedsLayout];
[view layoutIfNeeded];
self.frame = view.bounds;
CGFloat pickerHeaderViewHeight = self.pickerHeaderView ? self.pickerHeaderView.bounds.size.height : 0;
CGFloat pickerFooterViewHeight = self.pickerFooterView ? self.pickerFooterView.bounds.size.height : 0;
self.pickerView.frame = CGRectMake(0, pickerHeaderViewHeight, view.bounds.size.width, view.bounds.size.height - pickerHeaderViewHeight - pickerFooterViewHeight);
[self addSubview:self.pickerView];
} else {
[self.alertView addSubview:self.pickerView];
}
// 线
if (self.pickerStyle.clearPickerNewStyle) {
[self.pickerStyle addSeparatorLineView:self.pickerView];
}
// 2.
[self reloadData];
__weak typeof(self) weakSelf = self;
self.doneBlock = ^{
// block
if (weakSelf.resultBlock) {
weakSelf.resultBlock(weakSelf.selectProvinceModel, weakSelf.selectCityModel, weakSelf.selectAreaModel);
}
};
[super addPickerToView:view];
}
#pragma mark -
- (void)addSubViewToPicker:(UIView *)customView {
[self.pickerView addSubview:customView];
}
#pragma mark -
- (void)show {
[self addPickerToView:nil];
}
#pragma mark -
- (void)dismiss {
[self removePickerFromView:nil];
}
#pragma mark - setter
- (void)setSelectValues:(NSArray<NSString *> *)selectValues {
self.mSelectValues = selectValues;
}
#pragma mark - getter
- (NSArray *)provinceModelArr {
if (!_provinceModelArr) {
_provinceModelArr = [NSArray array];
}
return _provinceModelArr;
}
- (NSArray *)cityModelArr {
if (!_cityModelArr) {
_cityModelArr = [NSArray array];
}
return _cityModelArr;
}
- (NSArray *)areaModelArr {
if (!_areaModelArr) {
_areaModelArr = [NSArray array];
}
return _areaModelArr;
}
- (BRProvinceModel *)selectProvinceModel {
if (!_selectProvinceModel) {
_selectProvinceModel = [[BRProvinceModel alloc]init];
}
return _selectProvinceModel;
}
- (BRCityModel *)selectCityModel {
if (!_selectCityModel) {
_selectCityModel = [[BRCityModel alloc]init];
_selectCityModel.code = @"";
_selectCityModel.name = @"";
}
return _selectCityModel;
}
- (BRAreaModel *)selectAreaModel {
if (!_selectAreaModel) {
_selectAreaModel = [[BRAreaModel alloc]init];
_selectAreaModel.code = @"";
_selectAreaModel.name = @"";
}
return _selectAreaModel;
}
- (NSArray *)dataSourceArr {
if (!_dataSourceArr) {
_dataSourceArr = [NSArray array];
}
return _dataSourceArr;
}
- (NSArray<NSString *> *)mSelectValues {
if (!_mSelectValues) {
_mSelectValues = [NSArray array];
}
return _mSelectValues;
}
- (NSArray<NSNumber *> *)selectIndexs {
if (!_selectIndexs) {
_selectIndexs = [NSArray array];
}
return _selectIndexs;
}
@end