欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

IOS下省市区选择器实现[基于TableView]

程序员文章站 2023-08-24 10:00:44
最近做的ios项目中,要用到好几处地方要用到选择器。比如说很常用的地区选择器(省市区),在android平台下已经实现了自定义一个dialog。但是对ios并不太熟悉,去网上下载了...

最近做的ios项目中,要用到好几处地方要用到选择器。比如说很常用的地区选择器(省市区),在android平台下已经实现了自定义一个dialog。但是对ios并不太熟悉,去网上下载了一些例子,大多是用pickerview,然后省市区分三列,如:

 

这样的效果也不错,只是有些时候区名太长,就看不到了,而且没有按钮可以点。还有一个就是不能自己输入地址。

用户可以自己输入:

 看看源代码吧。

先是头文件:


[cpp] 
//  
//  nerveareaselectorviewcontroller.h  
//  
//  省市区三级选择器,可以自己输入  
//    
//  created by 集成显卡 on 13-5-17.  
//  copyright (c) 2013年 集成显卡 zxingming@qq.com . all rights reserved.  
//  
 
#import <uikit/uikit.h>  
 
typedef enum { 
    province, 
    city, 
    area 
} nerveselectoretype; 
 
//  
//选择器协议,在调用的viewcontroller中实现此协议即可  
//  
@protocol nerveareaselectdelegate <nsobject> 
 
@optional 
- (void)onareaselect:(nsstring *)selectvalue; 
- (void)onareacannel; 
@end 
 
@interface nerveareaselectorviewcontroller : uiviewcontroller <uitableviewdatasource, uitableviewdelegate>{ 
     
    nsarray *provinces, *cities, *areas; 
    nsstring *province, *city, *area; 
     
    nsinteger selecttype;//当前的选择类型,省,市,区  
     
    id<nerveareaselectdelegate> delegate; 

 
@property (weak, nonatomic) iboutlet uitextfield *areatx; 
@property (weak, nonatomic) iboutlet uitableview *areatableview; 
 
 
//  
//初始化数据  
//  
-(id) initwithdelegate:(id<nerveareaselectdelegate>) targetdelegate; 
 
//  
//确定按钮点击事件  
//  
- (ibaction)onokbtnclick:(id)sender; 
 
//  
//取消按钮点击事件  
//  
- (ibaction)okcannelbtnclick:(id)sender; 
 
//  
//隐藏键盘用的  
//  
- (ibaction)exitinput:(id)sender; 
 
@end 

//
//  nerveareaselectorviewcontroller.h
//
// 省市区三级选择器,可以自己输入
// 
//  created by 集成显卡 on 13-5-17.
//  copyright (c) 2013年 集成显卡 zxingming@qq.com . all rights reserved.
//

#import <uikit/uikit.h>

typedef enum {
    province,
    city,
    area
} nerveselectoretype;

//
//选择器协议,在调用的viewcontroller中实现此协议即可
//
@protocol nerveareaselectdelegate <nsobject>

@optional
- (void)onareaselect:(nsstring *)selectvalue;
- (void)onareacannel;
@end

@interface nerveareaselectorviewcontroller : uiviewcontroller <uitableviewdatasource, uitableviewdelegate>{
   
    nsarray *provinces, *cities, *areas;
    nsstring *province, *city, *area;
   
    nsinteger selecttype;//当前的选择类型,省,市,区
   
    id<nerveareaselectdelegate> delegate;
}

@property (weak, nonatomic) iboutlet uitextfield *areatx;
@property (weak, nonatomic) iboutlet uitableview *areatableview;


//
//初始化数据
//
-(id) initwithdelegate:(id<nerveareaselectdelegate>) targetdelegate;

//
//确定按钮点击事件
//
- (ibaction)onokbtnclick:(id)sender;

//
//取消按钮点击事件
//
- (ibaction)okcannelbtnclick:(id)sender;

//
//隐藏键盘用的
//
- (ibaction)exitinput:(id)sender;

@end

 

然后是具体实现类,这里主要讲一些主要的方法。

读取数据方法:


[cpp] 
-(id)initwithdelegate:(id<nerveareaselectdelegate>)targetdelegate{ 
    delegate = targetdelegate; 
     
    [self readdata]; 
     
    selecttype = province; 
    self.navigationcontroller.navigationbarhidden = no; 
    self.title = @"ssss"; 
     
     
    uibarbuttonitem* leftb = [[uibarbuttonitem alloc] init]; 
    leftb.title = @"ss"; 
    self.navigationitem.backbarbuttonitem = leftb; 
     
    return self; 

-(id)initwithdelegate:(id<nerveareaselectdelegate>)targetdelegate{
    delegate = targetdelegate;
   
    [self readdata];
   
    selecttype = province;
    self.navigationcontroller.navigationbarhidden = no;
    self.title = @"ssss";
   
   
    uibarbuttonitem* leftb = [[uibarbuttonitem alloc] init];
    leftb.title = @"ss";
    self.navigationitem.backbarbuttonitem = leftb;
   
    return self;
}
显示tablecell的方法:


[cpp] 
-(uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath{ 
    int index = [indexpath row]; 
    //int section = [indexpath section];  
    static nsstring* customcellidentifier = @"nerveareaselectorcell"; 
     
    uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:customcellidentifier]; 
     
    if(cell == nil){ 
        cell = [[uitableviewcell alloc] initwithstyle:uitableviewcellstylesubtitle reuseidentifier:customcellidentifier]; 
    } 
     
    switch (selecttype) { 
        case province: 
            cell.textlabel.text = [[provinces objectatindex:index] 
                                   objectforkey:@"state"]; 
            cell.accessorytype = uitableviewcellaccessorydetaildisclosurebutton; 
            break; 
        case city: 
            cell.textlabel.text = [[cities objectatindex:index] 
                                   objectforkey:@"city"]; 
            cell.accessorytype = uitableviewcellaccessorydetaildisclosurebutton; 
            break; 
        default: 
            cell.textlabel.text = [areas objectatindex:index]; 
            cell.accessorytype = uitableviewcellaccessorynone; 
            break; 
    } 
     
    return cell; 

-(uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath{
    int index = [indexpath row];
    //int section = [indexpath section];
    static nsstring* customcellidentifier = @"nerveareaselectorcell";
   
    uitableviewcell *cell = [tableview dequeuereusablecellwithidentifier:customcellidentifier];
   
    if(cell == nil){
        cell = [[uitableviewcell alloc] initwithstyle:uitableviewcellstylesubtitle reuseidentifier:customcellidentifier];
    }
   
    switch (selecttype) {
        case province:
            cell.textlabel.text = [[provinces objectatindex:index]
                                   objectforkey:@"state"];
            cell.accessorytype = uitableviewcellaccessorydetaildisclosurebutton;
            break;
        case city:
            cell.textlabel.text = [[cities objectatindex:index]
                                   objectforkey:@"city"];
            cell.accessorytype = uitableviewcellaccessorydetaildisclosurebutton;
            break;
        default:
            cell.textlabel.text = [areas objectatindex:index];
            cell.accessorytype = uitableviewcellaccessorynone;
            break;
    }
   
    return cell;
}
用户选择单元格时:


[cpp] 
//表格被选择  
-(void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath{ 
    int selectindex = [indexpath row]; 
    int cellcount = 0; 
    switch (selecttype) { 
        case province: 
            province = [[provinces objectatindex:selectindex] objectforkey:@"state"]; 
            cities = [[provinces objectatindex:selectindex] objectforkey:@"cities"]; 
             
            selecttype = city; 
            cellcount = [cities count]; 
            break; 
        case city: 
            city = [[cities objectatindex:selectindex] objectforkey:@"city"]; 
            areas = [[cities objectatindex:selectindex] objectforkey:@"areas"]; 
             
            selecttype = area; 
            cellcount = [areas count]; 
            break; 
        default: 
            area = [areas objectatindex:selectindex]; 
            break; 
    } 
     
    nsstring* areavalue = [nsstring stringwithformat:@"%@ %@ %@",province, city,area]; 
    nslog(@"select=%@", areavalue); 
     
    self.areatx.text = areavalue; 
     
    [areatableview reloaddata]; 
     
    if(cellcount > 0){ 
        nsindexpath* topindexpath = [nsindexpath indexpathforrow:0 insection:indexpath.section]; 
        [areatableview scrolltorowatindexpath:topindexpath atscrollposition:uitableviewscrollpositiontop animated:yes]; 
    } 

//表格被选择
-(void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath{
    int selectindex = [indexpath row];
    int cellcount = 0;
    switch (selecttype) {
        case province:
            province = [[provinces objectatindex:selectindex] objectforkey:@"state"];
            cities = [[provinces objectatindex:selectindex] objectforkey:@"cities"];
           
            selecttype = city;
            cellcount = [cities count];
            break;
        case city:
            city = [[cities objectatindex:selectindex] objectforkey:@"city"];
            areas = [[cities objectatindex:selectindex] objectforkey:@"areas"];
           
            selecttype = area;
            cellcount = [areas count];
            break;
        default:
            area = [areas objectatindex:selectindex];
            break;
    }
   
    nsstring* areavalue = [nsstring stringwithformat:@"%@ %@ %@",province, city,area];
    nslog(@"select=%@", areavalue);
   
    self.areatx.text = areavalue;
   
    [areatableview reloaddata];
   
    if(cellcount > 0){
        nsindexpath* topindexpath = [nsindexpath indexpathforrow:0 insection:indexpath.section];
        [areatableview scrolltorowatindexpath:topindexpath atscrollposition:uitableviewscrollpositiontop animated:yes];
    }
}
确定按钮被点击:


[cpp]
- (ibaction)onokbtnclick:(id)sender { 
    nslog(@"ok click"); 
    [delegate onareaselect:areatx.text]; 

- (ibaction)onokbtnclick:(id)sender {
    nslog(@"ok click");
    [delegate onareaselect:areatx.text];
}