Swift之三級聯(lián)動UIPickerView城市選擇器

初學(xué)swift語言沒幾天闸氮,就試著自己寫了一個城市選擇器折晦,純swift代碼。

ViewController.swift文件中漆改,個人編程習(xí)慣是把視圖生命周期心铃,視圖設(shè)置,相關(guān)代理方法實現(xiàn)籽懦,事件響應(yīng)于个,網(wǎng)絡(luò)請求等方法標(biāo)記后放在響應(yīng)代碼區(qū),正好可以利用swift語言的extension特性將代碼功能分類暮顺,這樣代碼不僅易讀厅篓,還有利于調(diào)試:

import UIKit

//MARK: View life cycle
class ViewController: UIViewController {

? ? /** 懶加載的城市數(shù)據(jù)源數(shù)組 */
? ? fileprivate lazy var cCityDataArray:[StateModel] = {
? ? //Plist文件路徑
? ? let path = Bundle.main.path(forResource: "area", ofType: "plist")
? ? var areas: NSArray? = nil
? ? //讀取Plist文件數(shù)組
? ? if let arrayPath = path {
? ? ? ? areas = NSArray (contentsOfFile: arrayPath)
? ? }
? ? //數(shù)組轉(zhuǎn)換為模型數(shù)組
? ? var cityData = Array()
? ? if let areasArr = areas {
? ? ? ? for area in areasArr {
? ? ? ? ? ? let areaDic = area as! NSDictionary
? ? ? ? ? ? let stateModel = StateModel.init(dictionary: areaDic)
? ? ? ? ? ? cityData.append(stateModel)
? ? ? ? }
? ? }
? ? return cityData
? ? }()
? ? /** 省級數(shù)據(jù)源數(shù)組 */
? ? fileprivate var cStatesArr: [StateModel]? = nil
? ? /** 市級數(shù)據(jù)源數(shù)組 */
? ? fileprivate var cCitiesArr: [CityModel]? = nil
? ? /** 區(qū)級數(shù)據(jù)源數(shù)組 */
? ? 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()
? ? ? ? self.view.backgroundColor = UIColor(red:0.85, green:0.85, blue:0.85, alpha:1.00)
? ? ? ? self.setupSubviews()
? ? ? ? //設(shè)置數(shù)據(jù)源數(shù)組初始值
? ? ? ? cStatesArr = cCityDataArray
? ? ? ? cCitiesArr = cStatesArr?.first?.cities
? ? ? ? cAreasArr = cCitiesArr?.first?.areas
? ? }

? ? override func didReceiveMemoryWarning() {
? ? ? ? super.didReceiveMemoryWarning()
? ? }
}

//MARK: Setup
extension ViewController {
? ? /** 設(shè)置subviews */
? ? fileprivate func setupSubviews() -> Void {
? ? self.setupTextField()
? ? self.setupCoverButton()
? ? self.setupPickerView()
? ? self.setupToolBar()
? ? }

? ? /** 設(shè)置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)
? ? ? ? }
? ? }
? ? /** 設(shè)置背景蒙版Button */
? ? private func setupCoverButton() -> Void {
? ? ? ? cTextFieldCoverButton.addTarget(self, action: #selector(clickTextFieldCoverButton(sender:)), for: UIControlEvents.touchUpInside)
? ? ? ? self.view.addSubview(cTextFieldCoverButton)
? ? ? ? cTextFieldCoverButton.isHidden = true
? ? }

? ? /** 設(shè)置pickerView */
? ? private func setupPickerView() -> Void {
? ? ? ? if let cityPickerView = cCityPickerView {
? ? ? ? ? ? cityPickerView.delegate = self
? ? ? ? ? ? cityPickerView.dataSource = self
? ? ? ? ? ? cCityTextField!.inputView = cityPickerView
? ? ? ? }
? ? }

? ? /** 設(shè)置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!.count
? ? ? ? case 1:
? ? ? ? ? ? return cCitiesArr!.count
? ? ? ? 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:
? ? ? ? ? ? //保存市級數(shù)據(jù)源數(shù)組
? ? ? ? ? ? cCitiesArr = cCityDataArray[row].cities
? ? ? ? ? ? //若有區(qū)級數(shù)據(jù),則保存區(qū)級數(shù)據(jù)源數(shù)組
? ? ? ? ? ? if cCitiesArr?.first?.areas != nil {
? ? ? ? ? ? ? ? cAreasArr = cCitiesArr?.first?.areas
? ? ? ? ? ? }
? ? ? ? ? ? //重新加載第1捶码、2組
? ? ? ? ? ? pickerView.reloadComponent(1)
? ? ? ? ? ? pickerView.reloadComponent(2)
? ? ? ? ? ? //默認(rèn)選中第1羽氮、2組的第1行數(shù)據(jù)
? ? ? ? ? ? pickerView.selectRow(0, inComponent: 1, animated: true)
? ? ? ? ? ? pickerView.selectRow(0, inComponent: 2, animated: true)
? ? ? ? case 1:
? ? ? ? ? ? //保存區(qū)級數(shù)據(jù)源數(shù)組
? ? ? ? ? ? if cCitiesArr![row].areas.count != 0 {
? ? ? ? ? ? ? ? cAreasArr = cCitiesArr![row].areas
? ? ? ? ? ? }
? ? ? ? ? ? //重新加載第2組數(shù)據(jù)
? ? ? ? ? ? pickerView.reloadComponent(2)
? ? ? ? ? ? //默認(rèn)選中第2組第1行數(shù)據(jù)
? ? ? ? ? ? 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.swift文件中,用于保存省級數(shù)據(jù):

import UIKit

/** 省級Model */
class StateModel: NSObject {
? ? /** 省下級所有城市 */
? ? let cities: Array
? ? /** 省級名稱 */
? ? let state: String

? ? init(dictionary: NSDictionary) {
? ? ? ? state = dictionary["state"] as! String
? ? ? ? let citiesArr = dictionary["cities"] as! NSArray
? ? ? ? var citiesMutableArr = Array()
? ? ? ? for city in citiesArr {
? ? ? ? ? ? let cityDic = city as! NSDictionary
? ? ? ? ? ? let cityModel = CityModel.init(dictionary: cityDic)
? ? ? ? ? ? citiesMutableArr.append(cityModel)
? ? ? ? }
? ? ? ? cities = citiesMutableArr
? ? }
}

CityModel.swift文件中惫恼,保存市/區(qū)級數(shù)據(jù):

import UIKit

//MARK: 城市Model
class CityModel: NSObject {
? ? /** 城市下級area */
? ? let areas: Array
? ? /** 城市名 */
? ? let city: String

? ? init(dictionary: NSDictionary){
? ? ? ? city = dictionary["city"] as! String
? ? ? ? let areasArr = dictionary["areas"] as! NSArray
? ? ? ? var areasMutableArr = Array()
? ? ? ? for area in areasArr {
? ? ? ? ? ? let areaString = area as! String
? ? ? ? ? ? areasMutableArr.append(areaString)
? ? ? ? }
? ? ? ? areas = areasMutableArr
}

}

博客地址:http://www.cnblogs.com/keqipu/?

qq:915621674

歡迎學(xué)習(xí)與交流


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末档押,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子祈纯,更是在濱河造成了極大的恐慌令宿,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腕窥,死亡現(xiàn)場離奇詭異粒没,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)簇爆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門癞松,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人入蛆,你說我怎么就攤上這事响蓉。” “怎么了哨毁?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵枫甲,是天一觀的道長。 經(jīng)常有香客問我挑庶,道長言秸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任迎捺,我火速辦了婚禮举畸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凳枝。我一直安慰自己抄沮,他們只是感情好跋核,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叛买,像睡著了一般砂代。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上率挣,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天刻伊,我揣著相機(jī)與錄音,去河邊找鬼椒功。 笑死捶箱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的动漾。 我是一名探鬼主播丁屎,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼旱眯!你這毒婦竟也來了晨川?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤删豺,失蹤者是張志新(化名)和其女友劉穎共虑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呀页,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡看蚜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赔桌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡渴逻,死狀恐怖疾党,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情惨奕,我是刑警寧澤雪位,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站梨撞,受9級特大地震影響雹洗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卧波,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一时肿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧港粱,春花似錦螃成、人聲如沸旦签。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宁炫。三九已至,卻和暖如春氮凝,著一層夾襖步出監(jiān)牢的瞬間羔巢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工罩阵, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留竿秆,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓永脓,卻偏偏與公主長得像袍辞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子常摧,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容