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

效果图

Static TableView 与UIPickerView的完美结合_第1张图片
图1

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


Static TableView 与UIPickerView的完美结合_第2张图片
图2

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

Static TableView 与UIPickerView的完美结合_第3张图片
图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()
    }
}

你可能感兴趣的:(Static TableView 与UIPickerView的完美结合)