iOS开发之UITableView联动实现城市选择器
lianghua
8年前
<p>在iOS开发之城市选择器一文中用两列的UIPickerView实现了城市选择器,今天用两个UITableView来实现一下,首先这种联动在很多地方用得上,而且方法有好几种,我这里选择了个人喜欢的一种方式:弄两个UITableView,让当前控制器管理。这种方式总体思路如下:</p> <p>1、添加两个UITableView到当前控制器中,分别设置它们的的尺寸,然后拖线到控制器中</p> <p>2、左边的表格设置数据源和代理为当前控制器,然后显示数据,右边的表格也设置数据源为当前控制器,然后显示数据操作。</p> <p>3、监听左边表格控制器的点击事件,在它的点击事件中刷新右边的表格</p> <p><strong>这时候就有问题了,一个控制器要成为2个UITableView的数据源和代理,怎么办?—— 在数据源和代理方法中,进行判断 if (self.leftTableView== tableView) {} else{}</strong></p> <p>具体步骤:</p> <p>1、添加2个UITableView,设置约束,设置数据源和代理,拖线到控制器,添加plist文件(和之前文中的一样,就不贴图了)。</p> <p><img src="https://simg.open-open.com/show/e4b2a957525dbca5edfcbb0ad046ee46.png"></p> <p style="text-align:center">添加和准备工作.png</p> <p>2、在控制器中实现功能,具体代码如下,注释非常详细:</p> <pre> <code class="language-objectivec">#import "ViewController.h" @interface ViewController () <UITableViewDataSource, UITableViewDelegate> #pragma mark 定义的属性 /** * 左边的表格 */ @property (weak, nonatomic) IBOutlet UITableView* leftTableView; /** * 右边的表格 */ @property (weak, nonatomic) IBOutlet UITableView* rightTableView; /** * plist对应的字典 */ @property (nonatomic, strong) NSDictionary* cityNames; /** * 省份 */ @property (nonatomic, strong) NSArray* provinces; /** * 城市 */ @property (nonatomic, strong) NSArray* cities; /** * 当前选择的省份 */ @property (nonatomic, copy) NSString* currentProvince; /** * 当前选择的城市 */ @property (nonatomic, copy) NSString* currentCity; @end @implementation ViewController #pragma mark 懒加载 /** * 懒加载plist * * @return plist对应的字典 */ - (NSDictionary*)cityNames { if (_cityNames == nil) { NSString* path = [[NSBundle mainBundle] pathForResource:@"cityData" ofType:@"plist"]; _cityNames = [NSDictionary dictionaryWithContentsOfFile:path]; } return _cityNames; } /** * 懒加载省份 * * @return 省份对应的数组 */ - (NSArray*)provinces { if (_provinces == nil) { //将省份保存到数组中 但是字典保存的是无序的 所以读出来的省份也是无序的 _provinces = [self.cityNames allKeys]; } return _provinces; } #pragma mark ViewController生命周期 - (void)viewDidLoad { [super viewDidLoad]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } #pragma mark UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { return 1; } - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section { //左边的返回省份即可 if (self.leftTableView == tableView) { return self.provinces.count; } //右边的要根据选中的行来设置 else { [self loadData]; return self.cities.count; } } - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath { if (self.leftTableView == tableView) { UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"leftCell"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"leftCell"]; } //左边显示省份 cell.textLabel.text = [self.provinces objectAtIndex:indexPath.row]; return cell; } else { UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"rightCell"]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"rightCell"]; } [self loadData]; //右边显示城市 cell.textLabel.text = [self.cities objectAtIndex:indexPath.row]; return cell; } } #pragma mark UITableViewDelegate - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { //点击左边加载右边的数据 if (self.leftTableView == tableView) { [self loadData]; [self.rightTableView reloadData]; } //点击右边显示用户选择的省份和城市 else { self.currentCity = [self.cities objectAtIndex:indexPath.row]; // 1.实例化:alertControllerWithTitle NSString* msg = [NSString stringWithFormat:@"%@ -- %@", self.currentProvince, self.currentCity]; UIAlertController* alert= [UIAlertController alertControllerWithTitle:@"选择城市" message:msg preferredStyle:UIAlertControllerStyleAlert]; // 2.添加按钮:actionWithTitle [alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction* action){ // 点击确定按钮的时候, 会调用这个block }]]; // 3.显示alertController:presentViewController [self presentViewController:alert animated:YES completion:nil]; } } #pragma mark Other /** * 根据左边选中的省份去加载右边的城市 */ - (void)loadData { //获左边取选中的行 NSInteger selRow = self.leftTableView.indexPathForSelectedRow.row; //选中行的省份 self.currentProvince = [self.provinces objectAtIndex:selRow]; //通过省份去获取对应的城市 self.cities = [self.cityNames valueForKey:self.currentProvince]; } @end</code></pre> <p>3、运行结果</p> <p><img src="https://simg.open-open.com/show/6a0e4f3c0e3a9d576accce4248e667c3.gif"></p> <p style="text-align:center">联动效果.gif</p> <p> </p> <p>来自:http://www.jianshu.com/p/483ba26a4c10</p> <p> </p>