Static TableView 与UIPickerView的完美结合

前言

在开发过程中,很多时候我们都在自定义tableview,在用户注册界面涉及性别或者出生年月的时候,这时候就需要tableview和pickerview的完美结合。由于开发工龄不大,我目前遇到过两种式样书:
1)点击cell,pickerview从下面弹出来
2)点击cell,插入一行cell(即插入pickerview)
第一种相对来说比较常见,写一个弹性动画即可实现,第二种有利于我们更好的理解tableview。

首先从object library中,拖拽一个UITableView 到 main.storyboard的UIViewController中,当你设置table view的Content为:Static Cells。这个时候就会发生神奇的事情,那就是会报错: static table views are only valid when embedded in UITableViewController instances。翻译下:tableview一定要添加到UITableViewController中。所以说我们要采取一些措施重新来操作一遍:
1、拖拽一个UITableViewController到storyboard中
2、创建一个继承UITableViewController的类
3、设置table view的Content为:Static Cells

效果图

图1

当我们点击出生年月的时候出现以下的效果:


图2

当我们点击性别的时候出现以下的效果:

图3

实现思路

1、我们在storyboard里面布局时会将4个row一起布局并设置好相应的约束。
2、设置2个Bool值(datePickerIsOpen,sexPickerIsOpen)去判断是否展开pickview。
3、在UITableViewDataSource代理中写展开与不展开时候返回的row的个数以及row的高度。
4、我们可以看见第一个图,只生成了row = 0 和 row = 2 的 cell。这主要是通过控制生成cell时候的indexPath。(图2、图3 同理)
5、在点击事件中,主要是一个插入和删除cell的操作

主要代码

class RegisterViewModel: NSObject {

    var datePickerIsOpen = false
    var sexPickerIsOpen = false
}

extension RegisterViewModel {
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        switch section {
        case 0: return 3
        case 1:
            if datePickerIsOpen == true && sexPickerIsOpen == false{
                return 3
            }else if datePickerIsOpen == false  && sexPickerIsOpen == false{
                return 2
            }else if sexPickerIsOpen == true  && datePickerIsOpen == false{
                return 3
            }else {
                return 4
            }
        default: break
        }
        return 0
    }

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        if datePickerIsOpen && indexPath.row == 1 && indexPath.section == 1{
            return 150
        }else if sexPickerIsOpen && indexPath.row == 2 && indexPath.section == 1{
            return 150
        }
        return 44
    }
}
class RegisterViewController: UITableViewController {

    @IBOutlet weak var datePickerView: UIDatePicker!
    @IBOutlet weak var sexPickerView: UIPickerView!

    @IBOutlet weak var dateShowLabel: UILabel!
    @IBOutlet weak var sexShowLabel: UILabel!
    private let sexDataSource = ["男","女","保密"]
    private var viewModel: RegisterViewModel = RegisterViewModel()

    override func viewDidLoad() {
        self.tableView.backgroundView = UIImageView.init(image: UIImage(named: "img_background"))
    }
}
extension RegisterViewController {

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return self.viewModel.tableView(tableView, numberOfRowsInSection: section)
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

        return self.viewModel.tableView(tableView, heightForRowAtIndexPath: indexPath)
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var indexPath = indexPath
        if self.viewModel.datePickerIsOpen == false && (indexPath.section == 1 && indexPath.row == 1){

            indexPath = NSIndexPath(forRow: indexPath.row + 1, inSection: 1)

        }else if self.viewModel.sexPickerIsOpen == true && (indexPath.section == 1 && indexPath.row == 2) {

            indexPath = NSIndexPath(forRow: indexPath.row + 1, inSection: 1)
        }

        return super.tableView(tableView, cellForRowAtIndexPath: indexPath)
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        tableView.deselectRowAtIndexPath(indexPath, animated: false)

        func showDatePicker() {
            if self.viewModel.sexPickerIsOpen == true {
                hiddenSexPicker()
            }
            self.viewModel.datePickerIsOpen = true
            tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: 1, inSection: 1)], withRowAnimation: .Fade)
        }
        func showSexPicker() {
            if self.viewModel.datePickerIsOpen == true {
                hiddenDatePicker()
            }
            self.viewModel.sexPickerIsOpen = true
            tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: 2, inSection: 1)], withRowAnimation: .Fade)
        }

        func hiddenDatePicker() {
            self.viewModel.datePickerIsOpen = false
            tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: 1, inSection: 1)], withRowAnimation: .Fade)
        }

        func hiddenSexPicker() {
            self.viewModel.sexPickerIsOpen = false
            tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: 2, inSection: 1)], withRowAnimation: .Fade)
        }

        func hiddenAll(){
            if self.viewModel.datePickerIsOpen {
                hiddenDatePicker()
            }else if self.viewModel.sexPickerIsOpen {
                hiddenSexPicker()
            }
        }
        if indexPath.section == 1 && indexPath.row == 0 {

            self.viewModel.datePickerIsOpen ? hiddenDatePicker(): showDatePicker()

        }else if self.viewModel.datePickerIsOpen && (indexPath.section == 1 && indexPath.row == 2) {

            showSexPicker()

        }else if !self.viewModel.datePickerIsOpen && (indexPath.section == 1 && indexPath.row == 1) {

            self.viewModel.sexPickerIsOpen ? hiddenSexPicker() : showSexPicker()
        }
        if indexPath.section == 0 {
            hiddenAll()
        }

    }
}
extension RegisterViewController: UIPickerViewDelegate,UIPickerViewDataSource {

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return sexDataSource.count
    }
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return sexDataSource[row]
    }

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        sexShowLabel.text = sexDataSource[row]
        self.sexShowLabel.layoutIfNeeded()
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容