Swift - 省市县三级联动功能的实现(使用UIPickerView选择框)

本文介绍如何使用 Swift 实现省、市、区三级联动的选择器功能。通过解析 plist 地址数据文件,利用 UIPickerView 控件实现联动效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

省、市、县(地区)的联动选择功能在实际项目中很常见。在之前的文章( Swift - 选择框(UIPickerView)的用法 )中,我介绍了  UIPickerView  的基本用法,本文演示如何实现联动功能。

1,三级联动效果图
(1)切换省时,后面市县两级数据会动态改变。
(2)切换市时,后面的县级数据会动态改变。
(3)点击“获取信息”,取得最终选择的省、市、县索引及其名字,并打印出来。
    原文:Swift - 省市县三级联动功能的实现(使用UIPickerView选择框)       原文:Swift - 省市县三级联动功能的实现(使用UIPickerView选择框)       原文:Swift - 省市县三级联动功能的实现(使用UIPickerView选择框)

2,地址信息文件
首先我们要准备一个包含所有地址信息的plist数据文件( address.plist),省市县的数据是一级级嵌套的树形结构,如下图:
原文:Swift - 省市县三级联动功能的实现(使用UIPickerView选择框)

部分数据节选如下(完整数据见我上传的源码包):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
< plist  version = "1.0" >
     < array >
         < dict >
             < key >cities</ key >
             < array >
                 < dict >
                     < key >areas</ key >
                     < array >
                         < string >普陀区</ string >
                         < string >定海区</ string >
                         < string >嵊泗县</ string >
                         < string >岱山县</ string >
                     </ array >
                     < key >city</ key >
                     < string >舟山</ string >
                 </ dict >
                 < dict >
                     < key >areas</ key >
                     < array >
                         < string >萧山区</ string >
                         < string >余杭区</ string >
                         < string >桐庐县</ string >
                         < string >淳安县</ string >
                         < string >临安市</ string >
                         < string >滨江区</ string >
                         < string >富阳市</ string >
                     </ array >
                     < key >city</ key >
                     < string >杭州</ string >
                 </ dict >
             </ array >
             < key >state</ key >
             < string >浙江</ string >
         </ dict >
         < dict >
             < key >cities</ key >
             < array >
                 < dict >
                     < key >areas</ key >
                     < array >
                         < string >连云区</ string >
                         < string >新浦区</ string >
                         < string >灌云县</ string >
                         < string >东海县</ string >
                     </ array >
                     < key >city</ key >
                     < string >连云港</ string >
                 </ dict >
             </ array >
             < key >state</ key >
             < string >江苏</ string >
         </ dict
     </ array >
</ plist >

3,功能实现
(1)程序启动后,首先从  address.plist 中将所有的地址数据读取出来,存储到本地变量(数组形式)。
(2) pickerView 默认加载所有省,以及第一个省的所有市数据,以及第一个市的所有县数据(如果有的话)。
(3)通过  pickerView 选中项的改变方法  didSelectRow,取得选中的列和行索引。随后调用  reloadComponent() 方法,根据索引刷新显示对应的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import  UIKit
 
class  ViewController : UIViewController UIPickerViewDelegate UIPickerViewDataSource {
 
     //选择器
     var  pickerView: UIPickerView !
     
     //所以地址数据集合
     var  addressArray = [[ String AnyObject ]]()
     
     //选择的省索引
     var  provinceIndex = 0
     //选择的市索引
     var  cityIndex = 0
     //选择的县索引
     var  areaIndex = 0
     
     override  func  viewDidLoad() {
         super .viewDidLoad()
         
         //初始化数据
         let  path =  NSBundle .mainBundle().pathForResource( "address" , ofType: "plist" )
         self .addressArray =  NSArray (contentsOfFile: path!)  as Array
        
         //创建选择器
         pickerView= UIPickerView ()
         //将dataSource设置成自己
         pickerView.dataSource= self
         //将delegate设置成自己
         pickerView.delegate= self
         self .view.addSubview(pickerView)
         
         //建立一个按钮,触摸按钮时获得选择框被选择的索引
         let  button= UIButton (frame: CGRectMake (0,0,100,30))
         button.center= self .view.center
         button.backgroundColor= UIColor .blueColor()
         button.setTitle( "获取信息" ,forState:. Normal )
         button.addTarget( self , action:#selector( ViewController .getPickerViewValue),
                          forControlEvents:  UIControlEvents . TouchUpInside )
         self .view.addSubview(button)
     }
     
     
     //设置选择框的列数为3列,继承于UIPickerViewDataSource协议
     func  numberOfComponentsInPickerView( pickerView:  UIPickerView ) ->  Int {
         return  3
     }
     
     //设置选择框的行数,继承于UIPickerViewDataSource协议
     func  pickerView(pickerView:  UIPickerView ,numberOfRowsInComponent component:  Int ) ->  Int {
         if  component == 0 {
             return  self .addressArray.count
         else  if  component == 1 {
             let  province =  self .addressArray[provinceIndex]
             return  province[ "cities" ]!.count
         else  {
             let  province =  self .addressArray[provinceIndex]
             if  let  city = province[ "cities" ]?[cityIndex]  as ? [ String AnyObject ] {
                 return  city[ "areas" ]!.count
             else  {
                 return  0
             }
         }
     }
     
     //设置选择框各选项的内容,继承于UIPickerViewDelegate协议
     func  pickerView(pickerView:  UIPickerView , titleForRow row:  Int , forComponent component:  Int )
         ->  String ? {
             if  component == 0 {
                 return  self .addressArray[row][ "state" as String
             } else  if  component == 1 {
                 let  province =  self .addressArray[provinceIndex]
                 return  province[ "cities" ]?[row][ "city" as String
             } else  {
                 let  province =  self .addressArray[provinceIndex]
                 let  city = province[ "cities" ]?[cityIndex]  as ! [ String AnyObject ]
                 return  city[ "areas" ]?[row]  as String
             }
     }
     
     //选中项改变事件(将在滑动停止后触发)
     func  pickerView(pickerView:  UIPickerView , didSelectRow row:  Int , inComponent component:  Int ) {
         //根据列、行索引判断需要改变数据的区域
         switch  (component) {
         case  0:
             provinceIndex = row;
             cityIndex = 0;
             areaIndex = 0;
             pickerView.reloadComponent(1);
             pickerView.reloadComponent(2);
             pickerView.selectRow(0, inComponent: 1, animated:  false );
             pickerView.selectRow(0, inComponent: 2, animated:  false );
         case  1:
             cityIndex = row;
             areaIndex = 0;
             pickerView.reloadComponent(2);
             pickerView.selectRow(0, inComponent: 2, animated:  false );
         case  2:
             areaIndex = row;
         default :
             break ;
         }
     }
     
     //触摸按钮时,获得被选中的索引
     func  getPickerViewValue(){
         //获取选中的省
         let  p =  self .addressArray[provinceIndex]
         let  province = p[ "state" ]!
         
         //获取选中的市
         let  c = p[ "cities" ]![cityIndex]
         let  city = c[ "city" as String
         
         //获取选中的县(地区)
         var  area =  ""
         if  (c[ "areas" as ! [ String ]).count > 0 {
             area = (c[ "areas" as ! [ String ])[areaIndex]
         }
         
         //拼接输出消息
         let  message =  "索引:\(provinceIndex)-\(cityIndex)-\(areaIndex)\n"
             "值:\(province) - \(city) - \(area)"
         
         //消息显示
         let  alertController =  UIAlertController (title:  "您选择了" ,
                                                 message: message, preferredStyle: . Alert )
         let  cancelAction =  UIAlertAction (title:  "确定" , style: . Cancel , handler:  nil )
         alertController.addAction(cancelAction)
         self .presentViewController(alertController, animated:  true , completion:  nil )
     }
}

原文出自: www.hangge.com   转载请保留原文链接: http://www.hangge.com/blog/cache/detail_1169.html
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值