Reputation: 2890
I am trying to display a date picker and update its time on button click.
I have a table view which shows business hours as shown in the below figure 1.
Figure 1
On clicking the timings cell or the time button inside the cell, I am expanding the cell to show date picker, I am unable to update the time in the date picker to the time on the time button.
For example when 9:00 AM is clicked, I would like to show 9:00 AM in the date picker as shown in below figure 2 or when 5:00 PM is clicked I would like to show 5:00 PM in date picker.
Also when the user changes the time in the date picker, I would like to update its corresponding time button in the tableview cell.
Figure 2
Below is the code, see code below comment //Updating the date picker
Since I am trying to update the date picker time inside a closure, it doesn't seem to work. Can someone please advice how I can fix this ?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
tableView.setEditing(true, animated: true) // This displays the delete button infront of the cell
tableView.allowsSelectionDuringEditing = true // Allows the table view cells to be selected during editing mode
if indexPath.section == 0 {
let cell = Bundle.main.loadNibNamed("DailyTimesTableViewCell", owner: self, options: nil)?.first as! DailyTimesTableViewCell
// Configure the cell...
cell.selectionStyle = UITableViewCellSelectionStyle.none; // Ensuring that there is no background for the selected cell
cell.datePicker.datePickerMode = .time // Setting start and time
cell.datePicker.minuteInterval = 5
cell.datePicker.addTarget(self, action: #selector(datePickerChanged), for: .valueChanged)
let startTime = timesArray[indexPath.row]["startTime"]
cell.startTime.setTitle(startTime as! String?, for: .normal)
cell.startTime.setTitleColor(UIColor.black, for: .normal)
let endTime = timesArray[indexPath.row]["endTime"]
cell.endTime.setTitle(endTime as! String?, for: .normal)
cell.endTime.setTitleColor(UIColor.black, for: .normal)
// Closure
cell.startTimeTapped = { (button : UIButton) -> Void in
// Updating the date picker
cell.datePicker.date = self.convertToDateObject(timeString: startTime as! String)
tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
// Expanding the cell to show date picker
if self.selectedCellIndexPath != nil && self.selectedCellIndexPath == indexPath {
tableView.cellForRow(at: indexPath)?.setEditing(true, animated: true) // This displays the delete button infront of the cell
self.selectedCellIndexPath = nil
} else {
self.selectedCellIndexPath = indexPath
}
}
// Closure
cell.endTimeTapped = { (button) -> Void in
// Updating the date picker
cell.datePicker.date = self.convertToDateObject(timeString: endTime as! String)
tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
// Expanding the cell to show date picker
if self.selectedCellIndexPath != nil && self.selectedCellIndexPath == indexPath{
tableView.cellForRow(at: indexPath)?.setEditing(true, animated: true)
self.selectedCellIndexPath = nil
}else{
self.selectedCellIndexPath = indexPath
}
}
return cell
}
}
DailyTimesTableViewCell code:
import UIKit
class DailyTimesTableViewCell: UITableViewCell, UITableViewDelegate {
typealias buttonTappedBlock = (_ button:UIButton) -> Void
var startTimeTapped : buttonTappedBlock!
var endTimeTapped : buttonTappedBlock!
@IBAction func startTimeClicked(_ sender: subclassedUIButton) {
if startTimeTapped != nil {
startTimeTapped(sender as UIButton)
}
}
@IBAction func endTimeClicked(_ sender: UIButton) {
if endTimeTapped != nil{
endTimeTapped(sender as UIButton)
}
}
}
Upvotes: 0
Views: 1088
Reputation: 2890
The answer for this part of the question:
I am unable to update the time in the date picker to the time on the time button
is the below code:
the issue was with this line of code tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.automatic)
and by adding tableView.beginUpdates()
, tableView.beginUpdates()
and returning the cell helped.
In the function cellForRow At
updated to the below code
cell.startTimeTapped = { (button) -> DailyTimesTableViewCell in
self.tableView.beginUpdates()
cell.datePicker.date = self.convertToDateObject(timeString: startTime as! String)
if self.selectedCellIndexPath != nil && self.selectedCellIndexPath == indexPath {
tableView.cellForRow(at: indexPath)?.setEditing(true, animated: true) // This displays the delete button infront of the cell
self.selectedCellIndexPath = nil
} else {
self.selectedCellIndexPath = indexPath
}
tableView.endUpdates()
return cell
}
In the class DailyTimesTableViewCell, updated to the below code
class DailyTimesTableViewCell: UITableViewCell, UITableViewDelegate {
typealias buttonTappedBlock = (_ button:UIButton) -> DailyTimesTableViewCell
var startTimeTapped : buttonTappedBlock!
var endTimeTapped : buttonTappedBlock!
@IBAction func startTimeClicked(_ sender: UIButton) {
if startTimeTapped != nil {
startTimeTapped(sender as UIButton)
}
}
}
Upvotes: 0
Reputation: 25280
To set date for your UIDatePicker
, simply use this piece of code to convert string formed time to a date
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "HH:mm"
let date = dateFormatter.dateFromString("17:00")//Put textfield.text! here
datePicker.date = date
For your second part of the question, since you may have multiple date pickers, what you need to do is to add selection change listener to all of them, then figure out which one is changed and also which label is clicked. Finally set the label to correct value.
You can use section number to find out which data picker is clicked. In your cellForRow
, add section as tag and then add the listener
datePicker.tag = indexPath.section
textView.tag = indexPath.section
datePicker.addTarget(self, action: Selector("dataPickerChanged:"), forControlEvents: UIControlEvents.ValueChanged)
Then in the listener function, find out which data picker has changed value
func datePickerChanged(datePicker:UIDatePicker) {
var dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
if datePicker.tag == 0 {
textView.text = dateFormatter.stringFromDate(datePicker.date)
}
// keep going
}
Upvotes: 1