iOS多級(jí)聯(lián)動(dòng)選擇器巴帮,地址溯泣、時(shí)間選擇(Swift3.0版)

iOS控件UIPickerView和DatePicker可實(shí)現(xiàn)滑動(dòng)選擇功能¢偶耄基于UIPickerView封裝多級(jí)聯(lián)動(dòng)(必須將可供選擇的數(shù)據(jù)緩存本地)垃沦,如省市區(qū)選擇實(shí)現(xiàn),效果如下:
Simulator Screen Shot 01.png

自定義LmyPickerObject類,定義要顯示的標(biāo)題雪猪、下一集子菜單集合栏尚,如果選擇省市區(qū)可添加屬性code。

public class LmyPickerObject: NSObject {
    
    var title:String?
    var subArray:[LmyPickerObject]?
    var code:String?
}

設(shè)置枚舉,融合兩種選擇器可配置译仗,還可添加其他可操作功能實(shí)現(xiàn)我們想要的效果抬虽。

public enum LmyPickerStyle : Int32 {
    
    case nomal
    
    case date
}

protocol PickerDelegate : NSObjectProtocol {

    func chooseElements(picker: LmyPicker, content: [Int:Int])
    func chooseDate(picker: LmyPicker, date: Date)
}

初始化LmyPicker,init方法

    var pickerDelegate : PickerDelegate?
    
    private let picker_height:CGFloat! = 260
    private var picker: UIPickerView = UIPickerView()
    private var datePicker: UIDatePicker = UIDatePicker()
    private var content: [LmyPickerObject]?
    private var pickerStyle: LmyPickerStyle?
    private var backgroundBtn: UIButton = UIButton()
    private var tempDic: Dictionary = [Int:Int]()
    private var numComponents:Int = 0
    
    var contentArray:[LmyPickerObject]? {
        get {
            return self.content
        }
        set {
            self.content = newValue
            self.initializeContentArray()
        }
    }

    init(delegate: PickerDelegate, style: LmyPickerStyle) {
        pickerDelegate = delegate
        pickerStyle = style
        let v_frame = CGRect(x: 0, y: UIScreen.height, width: UIScreen.width, height: picker_height)
        super.init(frame: v_frame)
        let view = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.width, height: 44))
        view.backgroundColor = UIColor.RGBA(230, 230, 230, 1)
        self.addSubview(view)
        
        let cancelBtn = UIButton(type: UIButtonType.system)
        cancelBtn.frame = CGRect(x: 0, y:  0, width: 60, height: 44)
        cancelBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
        cancelBtn.setTitle("取 消", for: UIControlState.normal)
        cancelBtn.setTitleColor(UIColor.RGBA(18, 93, 255, 1), for: UIControlState.normal)
        cancelBtn.addTarget(self, action: #selector(cancelButtonClick), for: .touchUpInside)
        self.addSubview(cancelBtn)
        
        let doneBtn = UIButton(type: UIButtonType.system)
        doneBtn.frame = CGRect(x: UIScreen.width - 60, y: 0, width: 60, height: 44)
        doneBtn.titleLabel?.font = UIFont.systemFont(ofSize: 16)
        doneBtn.setTitle("確 定", for: UIControlState.normal)
        doneBtn.setTitleColor(UIColor.RGBA(18, 93, 255, 1), for: UIControlState.normal)
        doneBtn.addTarget(self, action: #selector(doneButtonClick), for: .touchUpInside)
        self.addSubview(doneBtn)
        
        backgroundBtn = UIButton(type: UIButtonType.system)
        backgroundBtn.frame = CGRect(x: 0, y: 0, width: UIScreen.width, height: UIScreen.height)
        backgroundBtn.backgroundColor = UIColor.RGBA(0, 0, 0, 0.0)
        switch style {
        case .nomal:
            self.picker = UIPickerView(frame: CGRect(x: 0, y: 44, width: UIScreen.width, height: picker_height - 44))
            self.picker.delegate = self
            self.picker.dataSource = self
            self.picker.backgroundColor = UIColor.white
            self.addSubview(self.picker)
        case .date:
            self.datePicker = UIDatePicker(frame: CGRect(x: 0, y: 44, width: UIScreen.width, height: picker_height - 44))
            self.datePicker.datePickerMode = UIDatePickerMode.date
            self.datePicker.locale = Locale(identifier: "zh_CN")
            self.datePicker.backgroundColor = UIColor.white
            self.datePicker.addTarget(self, action: #selector(self.dateChoosePressed(datePicker:)), for: .valueChanged)
            self.addSubview(self.datePicker)
        }
    }
    private func initializeContentArray() {
        
        var temp:Int = 0
        if let array = content {
            if array.count > 0 {
                temp = 1
                tempDic[temp - 1] = 0
                var object = array.first
                while object?.subArray != nil {
                    temp += 1
                    tempDic[temp - 1] = 0
                    let arr = object?.subArray
                    if let temp_arr = arr {
                        if temp_arr.count > 0 {
                            object = temp_arr.first
                        }else {
                            break
                        }
                    }else{
                        break
                    }
                }
            }
        }
        numComponents = temp
        picker.reloadAllComponents()
    }
    public func show() {
        UIApplication.shared.keyWindow?.addSubview(self.backgroundBtn)
        UIApplication.shared.keyWindow?.addSubview(self)
        UIView.animate(withDuration: 0.35, animations: {
            self.backgroundBtn.backgroundColor = UIColor.RGBA(0, 0, 0, 0.3)
            self.top = UIScreen.height - self.picker_height
        }) { (finished: Bool) in
        }
    }
    private func hiddenPicker() {
        UIView.animate(withDuration: 0.35, animations: {
            self.backgroundBtn.backgroundColor = UIColor.RGBA(0, 0, 0, 0.0)
            self.top = UIScreen.height
        }) { (finished: Bool) in
            for view in self.subviews {
                view.removeFromSuperview()
            }
            self.removeFromSuperview()
            self.backgroundBtn.removeFromSuperview()
        }
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

UIPickerViewDelegate,UIPickerViewDataSource 時(shí)間方法纵菌,數(shù)據(jù)處理關(guān)鍵:

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return numComponents
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    var row:Int = 0
    if let array = content {
        var tempArray:Array = array
        for i in 0...numComponents {
            let value:Int = tempDic[i] ?? 0
            if component == i {
                row = tempArray.count
            }
            if tempArray.count > value {
                let object = tempArray[value]
                if let arr = object.subArray {
                    tempArray = arr
                }else {
                    tempArray = [LmyPickerObject]()
                }
            }
            if component == i {
                return row
            }
        }
        return 0
    }
    return 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if pickerStyle == .nomal {
        self.picker_partingLine(color: UIColor.lightGray)
    }
    var str:String = ""
    if let array = content {
        var tempArray:Array = array
        for i in 0...numComponents {
            let value:Int = tempDic[i] ?? 0
            if component == i {
                let object = tempArray[row]
                str = object.title ?? "未知"
            }
            if tempArray.count > value {
                let object = tempArray[value]
                if let arr = object.subArray {
                    tempArray = arr
                }else {
                    tempArray = [LmyPickerObject]()
                }
            }
        }
        return str
    }
    return ""
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    tempDic.updateValue(row, forKey: component)
    if (component + 1) < numComponents {
        for i in (component+1)..<numComponents {
            tempDic.updateValue(0, forKey:i)
            pickerView.selectRow(0, inComponent: i, animated: false)
        }
    }
    pickerView.reloadAllComponents()
}
func dateChoosePressed(datePicker: UIDatePicker) {
    //print("select date \(datePicker.date.string_from(formatter: "yyyy-MM-dd"))")
}

點(diǎn)擊取消或確定阐污,將結(jié)果傳到相應(yīng)控制器:

func doneButtonClick() {
    if pickerStyle == .nomal {
        pickerDelegate?.chooseElements(picker: self, content: tempDic)
    }else {
        pickerDelegate?.chooseDate(picker: self, date: datePicker.date)
    }
    self.hiddenPicker()
}
func cancelButtonClick(btn:UIButton) {
    self.hiddenPicker()
}

另外,不知為何從iOS10開始UIPickerView顯示選項(xiàng)分割線消失了咱圆,從網(wǎng)上找到代碼完美解決笛辟,應(yīng)該是默認(rèn)clearColor了。

func picker_partingLine(color: UIColor?) {
    let sep_color = color ?? UIColor.lightGray
    if #available(iOS 10.0, *) {
        for view in picker.subviews {
            if view.height < 1 {
                view.backgroundColor = sep_color
            }
        }
    }
}
    
結(jié)束

源碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末序苏,一起剝皮案震驚了整個(gè)濱河市手幢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌忱详,老刑警劉巖围来,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異匈睁,居然都是意外死亡监透,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門航唆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)胀蛮,“玉大人,你說(shuō)我怎么就攤上這事糯钙》嗬牵” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵超营,是天一觀的道長(zhǎng)鸳玩。 經(jīng)常有香客問(wèn)我阅虫,道長(zhǎng)演闭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任颓帝,我火速辦了婚禮米碰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘购城。我一直安慰自己吕座,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布瘪板。 她就那樣靜靜地躺著吴趴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪侮攀。 梳的紋絲不亂的頭發(fā)上锣枝,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天厢拭,我揣著相機(jī)與錄音,去河邊找鬼撇叁。 笑死供鸠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的陨闹。 我是一名探鬼主播楞捂,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼趋厉!你這毒婦竟也來(lái)了寨闹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤君账,失蹤者是張志新(化名)和其女友劉穎鼻忠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杈绸,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帖蔓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瞳脓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塑娇。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖劫侧,靈堂內(nèi)的尸體忽然破棺而出埋酬,到底是詐尸還是另有隱情,我是刑警寧澤烧栋,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布写妥,位于F島的核電站,受9級(jí)特大地震影響审姓,放射性物質(zhì)發(fā)生泄漏珍特。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一魔吐、第九天 我趴在偏房一處隱蔽的房頂上張望扎筒。 院中可真熱鬧,春花似錦酬姆、人聲如沸嗜桌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)骨宠。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間层亿,已是汗流浹背壶唤。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棕所,地道東北人闸盔。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像琳省,于是被迫代替她去往敵國(guó)和親迎吵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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