SwiftUI 中实现省市区选择器
作者:互联网
效果如下
import SwiftUI
struct ContentView: View {
@State private var addressItems: [Province] = []
@State private var areas: [String] = []
@State private var selectProvinceIndex = 0
@State private var selectCityIndex = 0
@State private var selectArea = ""
private func loadAddress(){
guard let addressFileUrl = Bundle.main.url(forResource: "Address", withExtension: "plist"), let data = try? Data(contentsOf: addressFileUrl) else{
return
}
let result = try! PropertyListDecoder().decode([Province].self, from: data)
self.addressItems = result
}
private func changeSelectAreas(selectCityIndex: Int){
let selectedCity = self.addressItems[safe: selectProvinceIndex]?.cities[safe: selectCityIndex]
if let areas = selectedCity?.areas{
self.areas = areas
self.selectArea = areas[safe: 0] ?? ""
}
}
var body: some View {
VStack{
Text("province: \(addressItems[safe: selectProvinceIndex]?.ProvinceName ?? "未选择")"+",city: \(addressItems[safe: selectProvinceIndex]?.cities[safe: selectCityIndex]?.cityName ?? "未选择")"+",area:\(addressItems[safe: selectProvinceIndex]?.cities[safe: selectCityIndex]?.areas[safe: 0] ?? "未选择")")
GeometryReader { geometry in
HStack(spacing: 0){
Picker("", selection: $selectProvinceIndex) {
ForEach(0..<addressItems.count,id: \.self) {index in
Text(addressItems[index].ProvinceName)
}
}
.onChange(of: selectProvinceIndex, perform: { newValue in
self.selectCityIndex = 0
changeSelectAreas(selectCityIndex:0)
})
.frame(width: geometry.size.width/3, alignment: .center)
.clipped()
Picker("", selection: $selectCityIndex) {
let cities = addressItems[safe: selectProvinceIndex]?.cities
if let cities = cities{
ForEach(0..<cities.count,id: \.self) {index in
Text(cities[safe: index]?.cityName ?? "")
}
}else{
EmptyView()
}
}
.onChange(of: selectCityIndex, perform: { newValue in
changeSelectAreas(selectCityIndex: newValue)
})
.frame(width: geometry.size.width/3, alignment: .center)
.clipped()
Picker("", selection: $selectArea) {
ForEach(areas,id: \.self) {
Text("\($0)")
}
}
.frame(width: geometry.size.width/3, alignment: .center)
.clipped()
}
}
}.onAppear(perform: {loadAddress()})
}
}
struct Province: Decodable{
let ProvinceName: String
var cities: [City] = []
enum CodingKeys: String, CodingKey{
case ProvinceName = "province"
case cities
}
}
struct City: Decodable{
let cityName: String
var areas: [String] = []
enum CodingKeys: String, CodingKey{
case cityName = "city"
case areas
}
}
extension Collection{
public subscript(safe index: Index) -> Element?{
return indices.contains(index) ? self[index] : nil
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Address.plist代码如下
首先创建一个Property.list文件,命名为Address
在Address.plist文件上右击open as ->Source Code
加入如下代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>province</key>
<string>河北省</string>
<key>cities</key>
<array>
<dict>
<key>areas</key>
<array>
<string>长安区</string>
<string>桥东区</string>
<string>桥西区</string>
<string>新华区</string>
<string>井陉矿区</string>
<string>裕华区</string>
<string>井陉县</string>
<string>正定县</string>
<string>栾城县</string>
<string>行唐县</string>
<string>灵寿县</string>
<string>高邑县</string>
<string>深泽县</string>
<string>赞皇县</string>
<string>无极县</string>
<string>平山县</string>
<string>元氏县</string>
<string>赵县</string>
<string>辛集市</string>
<string>藁城市</string>
<string>晋州市</string>
<string>新乐市</string>
<string>鹿泉市</string>
<key>area</key>
<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>
<string>滦南县</string>
<string>乐亭县</string>
<string>迁西县</string>
<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>
<dict>
<key>areas</key>
<array>
<string>邯山区</string>
<string>丛台区</string>
<string>复兴区</string>
<string>峰峰矿区</string>
<string>邯郸县</string>
<string>临漳县</string>
<string>成安县</string>
<string>大名县</string>
<string>涉县</string>
<string>磁县</string>
<string>肥乡县</string>
<string>永年县</string>
<string>邱县</string>
<string>鸡泽县</string>
<string>广平县</string>
<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>
<string>任县</string>
<string>南和县</string>
<string>宁晋县</string>
<string>巨鹿县</string>
<string>新河县</string>
<string>广宗县</string>
<string>平乡县</string>
<string>威县</string>
<string>清河县</string>
<string>临西县</string>
<string>南宫市</string>
<string>沙河市</string>
</array>
<key>city</key>
<string>邢台市</string>
</dict>
<dict>
<key>city</key>
<string>保定市</string>
<key>areas</key>
<array>
<string>新市区</string>
<string>北市区</string>
<string>南市区</string>
<string>满城县</string>
<string>清苑县</string>
<string>涞水县</string>
<string>阜平县</string>
<string>徐水县</string>
<string>定兴县</string>
<string>唐县</string>
<string>高阳县</string>
<string>容城县</string>
<string>涞源县</string>
<string>望都县</string>
<string>安新县</string>
<string>易县</string>
<string>曲阳县</string>
<string>蠡县</string>
<string>顺平县</string>
<string>博野县</string>
<string>雄县</string>
<string>涿州市</string>
<string>定州市</string>
<string>安国市</string>
<string>高碑店市</string>
</array>
</dict>
<dict>
<key>city</key>
<string>张家口市</string>
<key>areas</key>
<array>
<string>桥东区</string>
<string>桥西区</string>
<string>宣化区</string>
<string>下花园区</string>
<string>宣化县</string>
<string>张北县</string>
<string>康保县</string>
<string>沽源县</string>
<string>尚义县</string>
<string>蔚县</string>
<string>阳原县</string>
<string>怀安县</string>
<string>万全县</string>
<string>怀来县</string>
<string>涿鹿县</string>
<string>赤城县</string>
<string>崇礼县</string>
</array>
</dict>
<dict>
<key>city</key>
<string>秦皇岛市</string>
<key>areas</key>
<array>
<string>海港区</string>
<string>山海关区</string>
<string>北戴河区</string>
<string>青龙满族自治县</string>
<string>昌黎县</string>
<string>抚宁县</string>
<string>卢龙县</string>
</array>
</dict>
<dict>
<key>city</key>
<string>承德市</string>
<key>areas</key>
<array>
<string>双桥区</string>
<string>双滦区</string>
<string>鹰手营子矿区</string>
<string>承德县</string>
<string>兴隆县</string>
<string>平泉县</string>
<string>滦平县</string>
<string>隆化县</string>
<string>丰宁满族自治县</string>
<string>宽城满族自治县</string>
<string>围场满族蒙古族自治县</string>
</array>
</dict>
<dict>
<key>city</key>
<string>沧州市</string>
<key>areas</key>
<array>
<string>新华区</string>
<string>运河区</string>
<string>沧县</string>
<string>青县</string>
<string>东光县</string>
<string>海兴县</string>
<string>盐山县</string>
<string>肃宁县</string>
<string>南皮县</string>
<string>吴桥县</string>
<string>献县</string>
<string>孟村回族自治县</string>
<string>泊头市</string>
<string>任丘市</string>
<string>黄骅市</string>
<string>河间市</string>
</array>
</dict>
<dict>
<key>city</key>
<string>廊坊市</string>
<key>areas</key>
<array>
<string>安次区</string>
<string>广阳区</string>
<string>固安县</string>
<string>永清县</string>
<string>香河县</string>
<string>大城县</string>
<string>文安县</string>
<string>大厂回族自治县</string>
<string>霸州市</string>
<string>三河市</string>
</array>
</dict>
<dict>
<key>city</key>
<string>衡水市</string>
<key>areas</key>
<array>
<string>桃城区</string>
<string>枣强县</string>
<string>武邑县</string>
<string>武强县</string>
<string>饶阳县</string>
<string>安平县</string>
<string>故城县</string>
<string>景县</string>
<string>阜城县</string>
<string>冀州市</string>
<string>深州市</string>
</array>
</dict>
</array>
</dict>
</array>
</plist>
标签:city,selectProvinceIndex,safe,private,SwiftUI,var,省市区,选择器,areas 来源: https://www.cnblogs.com/chaostudy/p/15038765.html