• Swift3.0 三级联动UIPickerView城市选择器


      初学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,  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,  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
        }
        
    }
    

     

     

  • 相关阅读:
    C#面向对象五(继承、抽象类和抽象方法、多态、虚方法、is、as、new覆盖关键字)
    C#面向对象四(文件与目录操作、序列化与反序列化、XML)
    C#面向对象三(常用控件)
    C#面向对象二(集合泛型及排序)
    C#面向对象一(方法、封装、类、两种数据类型)
    如何最快找到重点 —— 小小码虫瞎想の效率与绩效篇(一)
    Android Telephony —— 手机信号实时变化源码分析过程记录
    Android 某些配置记录
    Macbook Pro 使用小记
    fhq treap 范浩强平衡树
  • 原文地址:https://www.cnblogs.com/keqipu/p/6536870.html
Copyright © 2020-2023  润新知