本篇文章為大家展示了怎么在iOS中實現(xiàn)一個三級聯(lián)動選擇器,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
創(chuàng)新互聯(lián)專注于越城企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),商城網(wǎng)站建設(shè)。越城網(wǎng)站建設(shè)公司,為越城等地區(qū)提供建站服務(wù)。全流程按需定制制作,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
1)怎么設(shè)置默認值,關(guān)鍵代碼
[self.pickerView selectRow:xxx inComponent:xxx animated:YES];
2)怎么讓三級之間聯(lián)動 ,關(guān)鍵代碼
[self pickerView:self.pickerView didSelectRow:0 inComponent:0 ];//聯(lián)動輪子1 必須得本輪有數(shù)據(jù)后觸發(fā)否則crash
先看下效果圖
關(guān)于設(shè)置默認值,三級聯(lián)動,用UIPickView的話就是有3個輪子(component),首先我們要想到,第一次向后臺發(fā)起請求,我們只能獲取到第0個component的數(shù)據(jù),只有當(dāng)你滾動輪子的時候才會獲取到省的Id發(fā)起請求來獲得該省的市的數(shù)據(jù),也就是第1個component的數(shù)據(jù),依此類推,滾動第1個component發(fā)起請求來獲取第2個component的數(shù)據(jù),因此,pickView的監(jiān)聽輪子滾動的代理起了重要作用
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component;
我們通過接口獲取第0個component的數(shù)據(jù),這邊是后臺規(guī)定的使用id=0,獲取到以后,默認選中第0個component的第0個row并主動調(diào)用觸發(fā)pick的輪子滾動代理來聯(lián)動第1個component【要在獲取數(shù)據(jù)成功后再執(zhí)行這部操作,因此放在數(shù)據(jù)請求成功的回調(diào)內(nèi)】,代碼為
[self pickerView:self.pickerView didSelectRow:0 inComponent:0 ];
在各輪子滾動過程中,用一個中間值
_selectedRow0記錄下第0個component的選中行
_selectedRow1記錄下第1個component的選中行
_selectedRow2記錄下第2個component的選中行,
這里需要記住,滾動某個輪子只能對它后面的輪子產(chǎn)生影響,所以當(dāng)滾動第0個component的時候使_selectedRow1,_selectedRow2均置為0,這里注意,上面提到的
默認選中第0個component的第0個row并主動調(diào)用觸發(fā)pick的輪子滾動代理來聯(lián)動第1個component
要先將輪子上的數(shù)據(jù)渲染好,設(shè)置好默認值才能主動調(diào)用監(jiān)聽輪子滾動的代理,否則會導(dǎo)致崩潰,另一個防崩潰的點如下圖
發(fā)現(xiàn)第三級沒數(shù)據(jù)的時候,如果你在代碼里沒加【安全措施】,那也會導(dǎo)致崩潰,要在請求到第三級的數(shù)據(jù)后做下判斷,如果個數(shù)為空,將該級對應(yīng)的數(shù)據(jù)源置為nil。(其它兩級的輪子最好也加判斷)
最后,由于這是個封裝的類,最終要得到選中的詳細信息,可通過代理或block傳值給controller。
又是你們最喜歡show code環(huán)節(jié):
.h文件
#import//定制代理協(xié)議 @protocol ZLMAddressPickerViewDelegate - (void)addressPickerViewDidSelected:(NSString *)areaName;//點擊上方完成按鈕的代理傳回拼接好的選中地址 - (void)addressPickerViewDidClose;//點擊關(guān)閉代理 @end @interface ZLMAddressPickerView : UIView @property (weak, nonatomic) id delegate; @end
.m文件
#import "ZLMAddressPickerView.h" #import "AFHttpUtils.h" #import "AreaModel.h" @interface ZLMAddressPickerView ()@property (strong, nonatomic) UIPickerView *pickerView; @property (strong, nonatomic) AreaModel *provBridge; @property (strong, nonatomic) AreaModel *cityBridge; @property (strong, nonatomic) AreaModel *areaBridge; @property (copy, nonatomic) NSArray * provDataArr;//省數(shù)組 @property (copy, nonatomic) NSArray * cityDataArr;//市數(shù)組 @property (copy, nonatomic) NSArray * areaDataArr;//區(qū)數(shù)組 @end @implementation ZLMAddressPickerView { NSInteger _selectRow0;//記錄第0個輪子的選擇行 NSInteger _selectRow1; NSInteger _selectRow2; NSString *_areaString;//最后要傳回的詳細地址拼接字符串 Area *_proModel;//記錄下選中省的數(shù)據(jù) Area *_cityModel; Area *_areaModel; } - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self setup]; } return self; } - (void)setup { _selectRow0 = 0; _selectRow1 = 0; _selectRow2 = 0; self.backgroundColor = [UIColor whiteColor]; UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), 44)]; toolbar.backgroundColor = [UIColor whiteColor]; [self addSubview:toolbar]; UIBarButtonItem *closeItem = [[UIBarButtonItem alloc] initWithTitle:@"關(guān)閉" style:UIBarButtonItemStylePlain target:self action:@selector(selectAddressClose)]; UIBarButtonItem *completeItem = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(selectAddressComplete)]; UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; toolbar.items = @[closeItem, spaceItem, completeItem]; self.pickerView.frame = CGRectMake(0, 44, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds) - 44); [self addSubview:self.pickerView]; [self downloadProv]; } #pragma mark - http methods /*省*/ - (void)downloadProv { NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary: @{@"id":@(0)} ]; [AFHttpUtils sendPostTaskWithUrl:[NSString stringWithFormat:@"%@/app/member/area",BASE_DOMAIN_URL] paramenters:dic successHandle:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"PROV:%@",responseObject); self.provBridge = [AreaModel mj_objectWithKeyValues:responseObject]; if (self.provBridge.error_code==0) { self.provDataArr=self.provBridge.data; [self pickerView:self.pickerView didSelectRow:0 inComponent:0 ];//聯(lián)動輪子1 必須得本輪有數(shù)據(jù)后才能觸發(fā)didselect [self.pickerView reloadAllComponents]; } } errorHandle:^(NSError *error) { }]; } /*市*/ - (void)downloadCityWithId:(NSInteger)provId { NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary: @{@"id":@(provId)} ]; [AFHttpUtils sendPostTaskWithUrl:[NSString stringWithFormat:@"%@/app/member/area",BASE_DOMAIN_URL] paramenters:dic successHandle:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"CITY:%@",responseObject); self.cityBridge = [AreaModel mj_objectWithKeyValues:responseObject]; if (self.cityBridge.error_code==0) { self.cityDataArr=self.cityBridge.data; [self.pickerView reloadComponent:1]; [self.pickerView selectRow:0 inComponent:1 animated:YES];//默認選擇row0 [self pickerView:self.pickerView didSelectRow:0 inComponent:1 ];//聯(lián)動輪子2 必須得本輪有數(shù)據(jù)后才能觸發(fā)didselect _cityModel = self.cityDataArr[_selectRow1]; [self downloadAreaWithId:_cityModel.area_id]; } } errorHandle:^(NSError *error) { }]; } /*區(qū)*/ - (void)downloadAreaWithId:(NSInteger)cityId { NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary: @{@"id":@(cityId)} ]; [AFHttpUtils sendPostTaskWithUrl:[NSString stringWithFormat:@"%@/app/member/area",BASE_DOMAIN_URL] paramenters:dic successHandle:^(NSURLSessionDataTask *task, id responseObject) { NSLog(@"AREA:%@",responseObject); self.areaBridge = [AreaModel mj_objectWithKeyValues:responseObject]; if (self.areaBridge.error_code==0&&self.areaBridge.data.count>0) { self.areaDataArr=self.areaBridge.data; }else{ self.areaDataArr=nil; } [self.pickerView reloadComponent:2]; [self.pickerView selectRow:0 inComponent:2 animated:YES]; [self pickerView:self.pickerView didSelectRow:0 inComponent:2 ]; } errorHandle:^(NSError *error) { }]; } #pragma mark - events response - (void)selectAddressComplete { [self.delegate addressPickerViewDidSelected:_areaString]; } - (void)selectAddressClose { [self.delegate addressPickerViewDidClose]; } #pragma mark - UIPickerViewDataSource //確定picker的輪子個數(shù) - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { return 3; } //確定picker的每個輪子的item數(shù) - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { if (component==0) { return self.provDataArr.count; }else if(component==1){ return self.cityDataArr.count; }else{ return self.areaDataArr.count; } } - (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component{ return 36; } //確定每個輪子的每一項顯示什么內(nèi)容 - (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component{ NSDictionary * attrDic = @{NSForegroundColorAttributeName:[UIColor blackColor], NSFontAttributeName:[UIFont systemFontOfSize:12]}; Area *area; if (component==0) { area = self.provDataArr[row]; }else if(component==1){ area = self.cityDataArr[row]; }else{ area = self.areaDataArr[row]; } NSAttributedString * attrString = [[NSAttributedString alloc] initWithString:area.name attributes:attrDic]; return attrString; } //監(jiān)聽輪子的移動 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { if (component==0) { _selectRow0 = [pickerView selectedRowInComponent:0]; _selectRow1 = 0; _selectRow2 = 0; _proModel = self.provDataArr[_selectRow0]; [self downloadCityWithId:_proModel.area_id]; }else if(component==1){ _selectRow1 = [pickerView selectedRowInComponent:1]; _selectRow2 = 0; _cityModel = self.cityDataArr[_selectRow1]; [self downloadAreaWithId:_cityModel.area_id]; }else{ _selectRow2 = [pickerView selectedRowInComponent:2]; if (self.areaDataArr&&self.areaDataArr.count>0) { _areaModel = self.areaDataArr[_selectRow2]; }else{ _areaModel = nil; } } if(_areaModel==nil){ _areaString = [NSString stringWithFormat:@"%@ %@",_proModel.name,_cityModel.name]; }else{ _areaString = [NSString stringWithFormat:@"%@ %@ %@",_proModel.name,_cityModel.name,_areaModel.name]; } } #pragma mark - getters and setters - (UIPickerView *)pickerView { if (_pickerView == nil) { _pickerView = [[UIPickerView alloc] init]; _pickerView.delegate = self; _pickerView.dataSource = self; } return _pickerView; } @end
最后在controller中調(diào)用
(1)導(dǎo)入
#import "ZLMAddressPickerView.h"
(2)定義一個對象并遵守代理協(xié)議
@property (strong, nonatomic) ZLMAddressPickerView *addressPickerView;
(3)懶加載生成對象(個人習(xí)慣)
- (ZLMAddressPickerView *)addressPickerView { if (!_addressPickerView) { _addressPickerView = [[ZLMAddressPickerView alloc] initWithFrame:CGRectMake(0, SCREEN_HEIGHT-244-64, SCREEN_WIDTH, 244)]; _addressPickerView.delegate = self; } return _addressPickerView; }
(4)在點擊跳出三級聯(lián)動選擇器的地方
[self.view addSubview:self.addressPickerView];
(5)別忘了實現(xiàn)代理
#pragma mark - ZLMAddressPickerViewDelegate - (void)addressPickerViewDidSelected:(NSString *)areaName { self.areaLabel.text = areaName;//將傳回的詳細地址字符串賦值 [self addressPickerViewDidClose]; } - (void)addressPickerViewDidClose { [self.addressPickerView removeFromSuperview]; }
上述內(nèi)容就是怎么在iOS中實現(xiàn)一個三級聯(lián)動選擇器,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。