城市选择器
效果
源码
https://github.com/YouXianMing/Animations
// // CustomCityPickerViewController.m // Animations // // Created by YouXianMing on 2017/9/12. // Copyright © 2017年 YouXianMing. All rights reserved. // #import "CustomCityPickerViewController.h" #import "PickerCityDataManager.h" #import "FileManager.h" #import "NSData+JSONData.h" #import "CustomPickerView.h" #import "PickerViewDataAdapter.h" #import "UIView+SetRect.h" #import "PickerProvinceView.h" #import "PickerCityView.h" #import "PickerAreaView.h" @interface CustomCityPickerViewController () <CustomPickerViewDelegate> @property (nonatomic, strong) NSArray <PickerProvinceModel *> *provinces; @property (nonatomic, strong) CustomPickerView *pickerView; @property (nonatomic, strong) PickerViewDataAdapter *pickerViewDataAdapter; @end @implementation CustomCityPickerViewController - (void)viewDidLoad { [super viewDidLoad]; // Get data. NSData *data = [NSData dataWithContentsOfFile:[FileManager bundleFileWithName:@"city.json"]]; NSArray *provinces = [data toListProperty]; self.provinces = [PickerCityDataManager provinceModelsWithArray:provinces]; // Create CustomPickerView's dataAdapter. self.pickerViewDataAdapter = [PickerViewDataAdapter pickerViewDataAdapterWithComponentsBlock:^(NSMutableArray<PickerViewComponent *> *components) { // Province component. PickerViewComponent *provinceComponent = [PickerViewComponent pickerViewComponentWithRowsBlock:^(NSMutableArray<PickerViewRow *> *rows) { [self.provinces enumerateObjectsUsingBlock:^(PickerProvinceModel *provinceModel, NSUInteger idx, BOOL * _Nonnull stop) { [rows addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerProvinceView class] data:provinceModel]]; }]; } componentWidth:Width / 3.f - 5.f]; // City component. PickerViewComponent *cityComponent = [PickerViewComponent pickerViewComponentWithRowsBlock:^(NSMutableArray<PickerViewRow *> *rows) { [self.provinces.firstObject.cities enumerateObjectsUsingBlock:^(PickerCityModel *cityModel, NSUInteger idx, BOOL * _Nonnull stop) { [rows addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerCityView class] data:cityModel]]; }]; } componentWidth:Width / 3.f - 5.f]; // Area component. PickerViewComponent *areaComponent = [PickerViewComponent pickerViewComponentWithRowsBlock:^(NSMutableArray<PickerViewRow *> *rows) { [self.provinces.firstObject.cities.firstObject.areas enumerateObjectsUsingBlock:^(PickerAreaModel *areaModel, NSUInteger idx, BOOL * _Nonnull stop) { [rows addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerAreaView class] data:areaModel]]; }]; } componentWidth:Width / 3.f - 5.f]; [components addObject:provinceComponent]; [components addObject:cityComponent]; [components addObject:areaComponent]; } rowHeight:60.f]; // Create CustomPickerView. self.pickerView = [[CustomPickerView alloc] initWithFrame:CGRectMake(0, 0, Width, 0) delegate:self pickerViewHeightType:kCustomPickerViewHeightTypeMax dataAdapter:self.pickerViewDataAdapter]; self.pickerView.center = self.contentView.middlePoint; [self.contentView addSubview:self.pickerView]; } #pragma mark - CustomPickerViewDelegate - (void)customPickerView:(CustomPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { if (component == 0) { NSMutableArray *citys = [NSMutableArray array]; [self.provinces[row].cities enumerateObjectsUsingBlock:^(PickerCityModel *cityModel, NSUInteger idx, BOOL * _Nonnull stop) { [citys addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerCityView class] data:cityModel]]; }]; NSMutableArray *areas = [NSMutableArray array]; [self.provinces[row].cities.firstObject.areas enumerateObjectsUsingBlock:^(PickerAreaModel *areaModel, NSUInteger idx, BOOL * _Nonnull stop) { [areas addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerAreaView class] data:areaModel]]; }]; pickerView.pickerViewDataAdapter.components[1].rows = citys; pickerView.pickerViewDataAdapter.components[2].rows = areas; [pickerView reloadComponent:1]; [pickerView reloadComponent:2]; [pickerView selectRow:0 inComponent:1 animated:YES]; [pickerView selectRow:0 inComponent:2 animated:YES]; } else if (component == 1) { NSInteger provinceIndex = [self.pickerView selectedRowInComponent:0]; NSMutableArray *areas = [NSMutableArray array]; // Protect crash. if (self.provinces[provinceIndex].cities.count <= row) { row = self.provinces[provinceIndex].cities.count - 1; } [self.provinces[provinceIndex].cities[row].areas enumerateObjectsUsingBlock:^(PickerAreaModel *areaModel, NSUInteger idx, BOOL * _Nonnull stop) { [areas addObject:[PickerViewRow pickerViewRowWithViewClass:[PickerAreaView class] data:areaModel]]; }]; pickerView.pickerViewDataAdapter.components[2].rows = areas; [pickerView reloadComponent:2]; [pickerView selectRow:0 inComponent:2 animated:YES]; } } - (void)customPickerView:(CustomPickerView *)pickerView didSelectedRows:(NSArray <NSNumber *> *)rows selectedDatas:(NSArray <id> *)datas { NSLog(@"%@", datas); } @end
特点
1. 每一个row都可以像使用UITableView的cell一样可以定制,继承CustomPickerView即可
2. 数据源通过PickerViewDataAdapter来指定,每一个PickerViewComponent都有一个PickViewRow的数组,每一个PickViewRow元素都对应一个自定义的CustomPickerView。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2015-09-12 NSMapTable、NSHashTable与NSPointerArray的封装
2014-09-12 使用截图工具FastStone Capture
2014-09-12 设置导航栏标题的文字属性