初学swift没几天,就试着自己写了一个城市选择器,纯swift代码。
ViewController.swift文件中:
// // ViewController.swift // swift demo - UIPickerView之城市选择器 // // Created by 柯其谱 on 17/3/11. // Copyright ? 2017年 柯其谱. All rights reserved. // import UIKit //MARK: View life cycle class ViewController: UIViewController { /** 懒加载的城市数据源数组 */ fileprivate lazy var cCityDataArray: [StateModel] = { //Plist文件路径 let path = Bundle.main.path(forResource: "area", ofType: "plist") var areas: NSArray? = nil //读取Plist文件数组 if let arrayPath = path { areas = NSArray (contentsOfFile: arrayPath) } //数组转换为模型数组 var cityData = Array<StateModel>() if let areasArr = areas { for area in areasArr { let areaDic = area as! NSDictionary let stateModel = StateModel.init(dictionary: areaDic) cityData.append(stateModel) } } return cityData }() /** 省级数据源数组 */ fileprivate var cStatesArr: [StateModel]? = nil /** 市级数据源数组 */ fileprivate var cCitiesArr: [CityModel]? = nil /** 区级数据源数组 */ fileprivate var cAreasArr: [String]? = nil /** 选择城市的textField */ fileprivate let cCityTextField: UITextField? = UITextField() /** 选择城市的pickerView */ fileprivate let cCityPickerView: UIPickerView? = UIPickerView() /** 选择城市的toolBar */ fileprivate let cCityToolBar: UIToolbar? = UIToolbar() /** 选择城市的背景蒙版 */ fileprivate let cTextFieldCoverButton: UIButton = UIButton (frame: UIScreen.main.bounds) override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = UIColor(red:0.85, green:0.85, blue:0.85, alpha:1.00) self.setupSubviews() //设置数据源数组初始值 cStatesArr = cCityDataArray cCitiesArr = cStatesArr?.first?.cities cAreasArr = cCitiesArr?.first?.areas } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } //MARK: Setup extension ViewController { /** 设置subviews */ fileprivate func setupSubviews() -> Void { self.setupTextField() self.setupCoverButton() self.setupPickerView() self.setupToolBar() } /** 设置textField */ private func setupTextField() -> Void { if let cityTextField = cCityTextField { cityTextField.frame = CGRect (x: 50, y: 200, width: 200, height: 44) cityTextField.delegate = self cityTextField.backgroundColor = UIColor.white cityTextField.placeholder = "请选择城市" cityTextField.borderStyle = UITextBorderStyle.roundedRect self.view.addSubview(cityTextField) } } /** 设置背景蒙版Button */ private func setupCoverButton() -> Void { cTextFieldCoverButton.addTarget(self, action: #selector(clickTextFieldCoverButton(sender:)), for: UIControlEvents.touchUpInside) self.view.addSubview(cTextFieldCoverButton) cTextFieldCoverButton.isHidden = true } /** 设置pickerView */ private func setupPickerView() -> Void { if let cityPickerView = cCityPickerView { cityPickerView.delegate = self cityPickerView.dataSource = self cCityTextField!.inputView = cityPickerView } } /** 设置toolBar */ private func setupToolBar() -> Void { if let cityToolBar = cCityToolBar { cityToolBar.frame = CGRect (x: 0, y: 0, width: 0, height: 44) cityToolBar.backgroundColor = UIColor.white let cancelItem = UIBarButtonItem.init(title: "取消", style: UIBarButtonItemStyle.done, target: self, action: #selector(clickToolBarCancelItem(sender:))) let spaceItem = UIBarButtonItem.init(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil) let doneItem = UIBarButtonItem.init(title: "确定", style: UIBarButtonItemStyle.done, target: self, action: #selector(clickToolBarDoneItem(sender:))) cityToolBar.items = [cancelItem, spaceItem, doneItem] cCityTextField?.inputAccessoryView = cityToolBar } } } //MARK: UITextFieldDelegate extension ViewController: UITextFieldDelegate { func textFieldDidBeginEditing(_ textField: UITextField) { cTextFieldCoverButton.isHidden = false } func textFieldDidEndEditing(_ textField: UITextField) { cTextFieldCoverButton.isHidden = true } } //MARK: UIPickerViewDelegate extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource { func numberOfComponents(in pickerView: UIPickerView) -> Int { return 3 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { switch component { case 0: return cStatesArr!.count case 1: return cCitiesArr!.count case 2: return cAreasArr!.count default: return 0 } } func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { switch component { case 0: return cStatesArr![row].state case 1: return cCitiesArr![row].city case 2: return cAreasArr![row] default: return nil } } func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat { return self.view.frame.width / 3 } func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { switch component { case 0: //保存市级数据源数组 cCitiesArr = cCityDataArray[row].cities //若有区级数据,则保存区级数据源数组 if cCitiesArr?.first?.areas != nil { cAreasArr = cCitiesArr?.first?.areas } //重新加载第1、2组 pickerView.reloadComponent(1) pickerView.reloadComponent(2) //默认选中第1、2组的第1行数据 pickerView.selectRow(0, inComponent: 1, animated: true) pickerView.selectRow(0, inComponent: 2, animated: true) case 1: //保存区级数据源数组 if cCitiesArr![row].areas.count != 0 { cAreasArr = cCitiesArr![row].areas } //重新加载第2组数据 pickerView.reloadComponent(2) //默认选中第2组第1行数据 pickerView.selectRow(0, inComponent: 2, animated: true) default: return } } } //MARK: Event response extension ViewController { @objc fileprivate func clickTextFieldCoverButton(sender: UIButton) -> Void { cCityTextField?.resignFirstResponder() } @objc fileprivate func clickToolBarCancelItem(sender: UIBarButtonItem) -> Void { cCityTextField?.resignFirstResponder() } @objc fileprivate func clickToolBarDoneItem(sender: UIBarButtonItem) -> Void { cCityTextField?.resignFirstResponder() let selectedState = cCityPickerView?.selectedRow(inComponent: 0) let selectedCity = cCityPickerView?.selectedRow(inComponent: 1) let selectedArea = cCityPickerView?.selectedRow(inComponent: 2) var cityString = (cStatesArr?[selectedState!].state)! + (cCitiesArr?[selectedCity!].city)! if cAreasArr?.count != 0 { cityString += (cAreasArr?[selectedArea!])! } cCityTextField?.text = cityString } }
StateModel.swfit文件中,用于保存省级数据:
// // StateModel.swift // swift demo - UIPickerView之城市选择器 // // Created by 柯其谱 on 17/3/11. // Copyright ? 2017年 柯其谱. All rights reserved. // import UIKit /** 省级Model */ class StateModel: NSObject { /** 省下级所有城市 */ let cities: Array<CityModel> /** 省级名称 */ let state: String init(dictionary: NSDictionary) { state = dictionary["state"] as! String let citiesArr = dictionary["cities"] as! NSArray var citiesMutableArr = Array<CityModel>() for city in citiesArr { let cityDic = city as! NSDictionary let cityModel = CityModel.init(dictionary: cityDic) citiesMutableArr.append(cityModel) } cities = citiesMutableArr } }
CityModel.swift文件中,用于保存市级数据
// // CityModel.swift // swift demo - UIPickerView之城市选择器 // // Created by 柯其谱 on 17/3/11. // Copyright ? 2017年 柯其谱. All rights reserved. // import UIKit //MARK: 城市Model class CityModel: NSObject { /** 城市下级area */ let areas: Array<String> /** 城市名 */ let city: String init(dictionary: NSDictionary){ city = dictionary["city"] as! String let areasArr = dictionary["areas"] as! NSArray var areasMutableArr = Array<String>() for area in areasArr { let areaString = area as! String areasMutableArr.append(areaString) } areas = areasMutableArr } }
时间: 2024-12-29 15:59:27