Toggling between two date Pickers in a table view?

Hi, I'm going over the - Hotel Manzana - project in "Develop in Swift - Data Collections". The app is for the registration and room assignment for a hotel. I must include the Check In date and the Check out date for the which I'm using a date picker for both set in a 4 row section in a table view just like in the next image:

When running the app the Date pickers must be hidden. And to activate one must press the check in or check out section just like this:

Only one date picker must be shown at a time for which if I select one and the other is shown, then only the one I selected must be shown and the other must be hidden. However at the time of execution I can only open one Date Picker and close it one time. After that it won't show me neither of the date pickers again, no matter how much I press the check in or check out rows in the table view, they'll stay hidden after the first time I opened them...

My code is as follows:




class AddRegistrationTableViewController: UITableViewController {

    

    @IBOutlet weak var firstNameTextField: UITextField!

    @IBOutlet weak var lastNameTextField: UITextField!

    @IBOutlet weak var emailTextField: UITextField!

    

    @IBOutlet weak var checkInDateLabel: UILabel!

    @IBOutlet weak var checkInDatePicker: UIDatePicker!

    @IBOutlet weak var checkOutDateLabel: UILabel!

    @IBOutlet weak var checkOutDatePicker: UIDatePicker!

    

    var formattedDate: DateFormatter = {

        let formattedDate = DateFormatter()

        formattedDate.dateStyle = .medium

        

        return formattedDate

    }()

    

    let checkInDateLabelCellIndexPath = IndexPath(row: 0, section: 1)

    let checkInDatePickerCellIndexPath = IndexPath(row: 1, section: 1)

    let checkOutDateLabelCellIndexPath = IndexPath(row: 2, section: 1)

    let checkOutDatePickerCellIndexPath = IndexPath(row: 3, section: 1)

    

    var isCheckInDatePickerVisible: Bool = false {

        didSet {

            checkInDatePicker.isHidden = !isCheckInDatePickerVisible

        }

    }

    

    var isCheckOutDatePickerVisible: Bool = false {

        didSet {

            checkOutDatePicker.isHidden = !isCheckOutDatePickerVisible

        }

    }

    

    override func viewDidLoad() {

        super.viewDidLoad()



        // Uncomment the following line to preserve selection between presentations

        // self.clearsSelectionOnViewWillAppear = false



        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.

        // self.navigationItem.rightBarButtonItem = self.editButtonItem

        let midnight = Calendar.current.startOfDay(for: Date())

        checkInDatePicker.minimumDate = midnight

        checkInDatePicker.date = midnight

        updateDateViews()

    }

    

    func updateDateViews() {

        checkOutDatePicker.minimumDate = Calendar.current.date(byAdding: .day, value: 1, to: checkInDatePicker.date)

        

        checkInDateLabel.text = formattedDate.string(from: checkInDatePicker.date)

        checkOutDateLabel.text = formattedDate.string(from: checkOutDatePicker.date)

    }

    

    @IBAction func doneBarButtonTapped(_ sender: UIBarButtonItem) {

        let firstName = firstNameTextField.text ?? ""

        let lastName = lastNameTextField.text ?? ""

        let email = emailTextField.text ?? ""

        let checkInDate = checkInDatePicker.date

        let checkOutDate = checkOutDatePicker.date

        

        print("firstName: \(firstName)")

        print("lastName: \(lastName)")

        print("email: \(email)")

        print("checkInDate: \(checkInDate)")

        print("checkOutDate: \(checkOutDate)")

    }

    

    

    @IBAction func datePickerValueChanged(_ sender: UIDatePicker) {

        updateDateViews()

    }

    



    // MARK: - Table view data source



    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {

        switch indexPath {

        case checkInDatePickerCellIndexPath where isCheckInDatePickerVisible == false:

            return 0

        case checkOutDatePickerCellIndexPath where isCheckOutDatePickerVisible == false:

            return 0

        default:

            return UITableView.automaticDimension

        }

    }

    

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        tableView.deselectRow(at: indexPath, animated: true)

        

        if indexPath == checkInDateLabelCellIndexPath && isCheckOutDatePickerVisible == false {

            isCheckInDatePickerVisible.toggle()

            if checkInDatePicker.isHidden == false {

                print("Check in date picker visible")

            } else {

                print("Check in date picker not visible")

            }

        } else if indexPath == checkOutDateLabelCellIndexPath && isCheckInDatePickerVisible == false {

            isCheckOutDatePickerVisible.toggle()

            if checkOutDatePicker.isHidden == false {

                print("Check out date picker visible")

            } else {

                print("Check out date picker not visible")

            }

        } else if indexPath == checkInDateLabelCellIndexPath || indexPath == checkOutDateLabelCellIndexPath {

            isCheckInDatePickerVisible.toggle()

            isCheckOutDatePickerVisible.toggle()

        } else {

            return

        }

        tableView.beginUpdates()

        tableView.endUpdates()

    }

As you can see in tableView(_: didSelectRow) I added two conditional if statements to print to the console if either isCheckInDatePickerVisible and isCheckOutDatePicker are visible or not. Both of these do work and actually tell me that the value really is changing but my interface won't update and show me the date pickers more than one time .

Answered by Claude31 in 694876022

I do not see in your code where is tableView(cellForRow) ?

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

.

The simplest would be to manage all this with your dataSource.

var pickers : [DatePicker] = []

In your code, you would have

pickers = [checkInDatePicker]

or

pickers = [checkOutDatePicker]

Note a question: why do you need to define isCheckOutDatePickerVisible and not use simply isCheckOutDatePicker.isHidden

For instance,

        } else if indexPath == checkOutDateLabelCellIndexPath && isCheckInDatePickerVisible == false {

would become

        } else if indexPath == checkOutDateLabelCellIndexPath && icheckInDatePicker.isHidden {

Or

            isCheckInDatePickerVisible.toggle()

would become

            checkInDatePicker.isHidden.toggle()

That could simplify code a lot.

Now a hint.

Why do you:

        tableView.beginUpdates()

        tableView.endUpdates()

with nothing inside

And not simply

tableView.reload()
Accepted Answer

I do not see in your code where is tableView(cellForRow) ?

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

.

The simplest would be to manage all this with your dataSource.

var pickers : [DatePicker] = []

In your code, you would have

pickers = [checkInDatePicker]

or

pickers = [checkOutDatePicker]

Note a question: why do you need to define isCheckOutDatePickerVisible and not use simply isCheckOutDatePicker.isHidden

For instance,

        } else if indexPath == checkOutDateLabelCellIndexPath && isCheckInDatePickerVisible == false {

would become

        } else if indexPath == checkOutDateLabelCellIndexPath && icheckInDatePicker.isHidden {

Or

            isCheckInDatePickerVisible.toggle()

would become

            checkInDatePicker.isHidden.toggle()

That could simplify code a lot.

Now a hint.

Why do you:

        tableView.beginUpdates()

        tableView.endUpdates()

with nothing inside

And not simply

tableView.reload()
Toggling between two date Pickers in a table view?
 
 
Q