In this blogpost I’d like to show you some code examples like we did in the form of some video tutorials that show you how to add the UIDatePicker or DateCell embedded in UITableView in Swift.
The DateCell example was originally implemented by Apple as part of an Objective C project, and you can download it here Apple DateCell.
I have Googleed to see if there is already a DateCell implementation in Swift, and found a lot of projects. Being a great advocate of the open source movement, I have preferred to choose the one that is already available and use it in this video tutorial. The reason I chose the https://github.com/KoheiHayakawa/DateCell project was that it was the most identical conversion of the Apple DateCell project I could find. So I chose him. Although, to be honest, I find Apple’s DateCell project a little confusing and I think there is an easier way to get the same results.
This is what the last example will look like when we create and run our application:
Below is a full example code in Swift, as well as three video tutorials showing how to do it:
- Creation of a user interface to work with the UIDatePicker integrated with UITableView,
- Add the Swift code from the DateCell project
- Configure UITableView to show how the built-in UIDatePicker can be added to other cells in the table,
- how to change the date format, and
- This gives you the selected date and time and converts it to an NSDate object for later use.
UIDatePicker of DateCell source code in Swift.
Uikit Input
ViewController class : UIViewController, UITableViewDataSource, UITableViewDelegate {….
kPickerAnimationDuration = 0.40 // Duration of the animation to move the date selection to frame
, kDatePickerTag = 99 // Frame tag to identify the date selection frame.
Leave kTitleKey = Header row // Key to get the header row of the data source element
Leave kDateKey = Date // Key to get the date value of the data source element
// See which rows of date cells have
leave kDateStartRow = 4
leave kDateEndRow = 5
let kDateCellID = dateCell; // cells with start or end date
let kDatePickerCellID = datePickerCellID; // cell with Date-Picker
let kOtherCellID = otherCellID; // cells remaining at the end
var data array : Cord: Any]]] = []
var dateFormatter = DateFormatter()
// which indexPath points to a cell with UIDatePicker
var datePickerIndexPath NSIndexPath?
var pickerCellRowHeight : CGFloat = 216
@IBOutlet weak var myTableView : VIEWABILITY!
viewDidLoad() {super.viewDidLoad()// Make additional settings after loading the view, usually from the pen.myTableView = UITableView()myTableView.delegate = set our data source toleave itemOne = [kTitleKey : Touch a cell to change the date:]
exits the dotTwo = [kTitleKey : Start date, kDateKey: NSDate()] as [character string : All]
exits point three = [kTitleKey : End date, kDateKey: NSDate()] as [character string : All]
stops with ArticleFour = [kTitleKey: (other number1)]
stops with ArticleFive = [kTitleKey: (other number2)]
stops with ArticleSix = [kTitleKey: (other number3)]
dataArray = [numberOne, ArticleFour, ArticleFive, ArticleSix, ArticleTwo, ArticleThree].
dateFormatter.dateStyle = .medium // show short date format
dateFormatter.timeStyle = .short
// if the locale changes in the background, we must be logged in so that we can update the date
// the format in the display cells of table
//
NotificationCenter.default.addObserver (self, selector: #selector (self.localeChanged), name: NSLocale.currentLocaleDidChangeNotification, object: nil).
}
// MARKET: – Location
/* ! Responsibility for changing the regional format or locale.*/@objc localeChanged(notification: NSNotification) {// The user has changed the local (regional format) in the settings, therefore we are informed here about //myTableView.reloadData()}.
Overwrite the didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Have all the resources that can be newly created available.
}
tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
ifInlineDatePicker() {
// we have a date picker, so enable it to return dataArray.count + 1;
} in the number of rows in this section.
Resend dataArray.count;
}
tableView(_ tableView : UITableView, cellForRowAt indexPath : IndexPath) -> UITableViewCell
{
var cell : VIEW REQUEST CELL?
var cellID = kOtherCellID
if indexPathPathHasPicker(indexPath : indexPath) {
// Path indexPath is the one with the online date picker
cellID = kDatePickerCellID // Cell with the current/open date picker
} otherwise if indexPathHasDate(indexPath) : indexPath) {
// Path indexPath is the one containing the date information
cellID = kDateCellID // Cell with start/end date
}
cell = tableView.dequeueReusableCell (metIdentifier: cellID)
if indexPath.row == 0 {/// we conclude here that the first cell of the array is not selected (it is only an indicator cell) ?}
// if we have an open cell of the date selector whose cell is larger than the cell we want to update,
// we have one cell more than the
modelRow line allows //
var modelRow = indexPath.row
as (datePickerIndexPath!= nil && datePickerIndexPath !.row <= indexPath.row) { modelRow -= 1 } ; leave itemData = dataArray [modelRow] as cellID == kDateCellID { // we have a start or end cell of a date, fill in the date field // cell? textLabel? text = itemData [kTitleKey] as ? A cell of a string ?.detailTextLabel?.text = self.dateFormatter.string(from: itemData[kDateKey] as! date) } otherwise, if cellID == kDateCellID { // this cell is not a date cell, just give it a text label // cell ?.textLabel?.text = itemData[kTitleKey] as? Back to your cell! } tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { leave cell = tableView.cellForRow(at: indexPath) as cell? reuseIdentifier == kDateCellID { //displayInlineDatePickerForRowAtIndexPath(at: indexPath) } otherwise { tableView.deselectRow(at: indexPath, animated: true) } } tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{….
return (indexPathHasPicker(indexPath: indexPath) ? pickerCellRowHeight: tableView.rowHeight)
}
/* ! Sets whether UITableViewController has a UIDatePicker in one of its cells. Function
*/
hasInlineDatePicker() -> Bool {
Return datePickerIndexPath != null
}.
/* ! Defines whether a certain indexPath refers to a cell with a UIDatePicker.
@param indexPath Check if it represents a cell with UIDatePicker.
*/
indexPathHasPicker(indexPath: IndexPath) -> Bool {
givesInlineDatePicker() && datePickerIndexPath?.row == indexPath.row
}.
/* ! Defines whether a particular indexPath refers to a cell with start/end data.
@param indexPath Check if it represents the start date cell.
*/
indexPathHasDate (indexPath : IndexPath) -> Bool {
var hasDate = false
if (indexPath.row == kDateStartRow) | (indexPath.row == kDateEndRow | (hasInlineDatePicker() && (indexPath.row == kDateEndRow + 1)). {hasDate = true}Returns hasDate}
/* ! The date selection appears in the string for the specified path, called doSelectRowAtIndexPath.
@param indexPath indexPath to open UIDatePicker.
*/
viewInlineDatePickerForRowAtIndexPath (indexPath: IndexPath) -> Bool {
// display the date sensor in line with the contents of table
self.myTableView.startUpdates()
var before = false // indicates whether the date picker is below indexPath, helps us determine which line
represents, ifInlineDatePicker() {
before = datePickerIndexPath !.row < indexPath.row } let sameCellClicked = (datePickerIndexPath ?.row == indexPath.row + 1) // delete any date selection cell, if it exists, if self.hasInlineDatePicker() { self.myTableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: datePickerIndexPath!.row, inSection: 0)], metRowAnimation: .Fade) datePickerIndexPath = nil } as !sameCellClicked { // hides the old date picker and displays the new one, so rowToReveal = (for ? indexPath.row – 1: indexPath.row) let indexPathToReveal = NSIndexPath(forRow: rowToReveal, inSection: 0) toggleDatePickerForSelectedIndexPath(indexPathToReveal) datePickerIndexPath = NSIndexPath(forRow: indexPathToReveal.row + 1, inSection: 0) }. // always delete the selection of the row with the start or end date self.myTableView.deselectRowAtIndexPath(indexPath, animated:true) self.myTableView.endUpdates() // inform our date provider of the current date according to the current update of the DatePicker() } cell. /* ! Add or remove a UIDatePicker cell under the specified indexPath. @param indexPath The path to open the UIDatePicker. */ activate toggleDatePickerForSelectedIndexPath (indexPath: NSIndexPath) { self.myTableView.startUpdates() let indexPaths = [NSIndexPath(forRow: indexPath.row + 1, inSection: 0)] // check if there is a date selection cell under indexPath if PickerForIndexPath(indexPath) [// has found a selection cell under this cell and delete it itself.myTableView.deleteRowsAtIndexPaths(indexPaths, withRowAnimation: .Fade) } otherwise { // didn’t find the selector below, so insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Fade) } self.myTableView.endUpdates() }. /* ! Update the UIDatePicker value to match the date in the cell above. */ activate updateDatePicker() { if indexPath = datePickerIndexPath { leave associatedDatePickerCell = self.myTableView.cellForRowAtIndexPath(indexPath) if targetDatePicker = associatedDatePickerCell?.viewWithTag(kDatePickerTag) as ! UIDatePicker? { leave itemData = dataArray [self.datePickerIndexPath !.row – 1] targetDatePicker.setDate(itemData[kDateKey] as! NSDate, animated: false) } } /*! Defines whether a UIDatePicker cell is under this index path. @param indexPath Checks whether there is a UIDatePicker under the indexPath cell. */Function hasPickerForIndexPath (indexPath : NSIndexPath) -> Bool {
var hasDatePicker = false
let targetRow = indexPath.row + 1
letDatePickerCell = self.myTableView.cellForRow(op: Check IndexPath(line: targetRow, section: 0)).
checkDatePicker = checkDatePickerCell?.viewWithTag(kDatePickerTag)
hasDatePicker = checkDatePicker != zero
Return hasDatePicker
}
@IBAction Functionality dateAction (Sender: UIDatePicker) {
var targetCellIndexPath : Index pad?
if self.hasInlineDatePicker() {
// InlineDatePicker: updates the date of the cell above the date picker cell
//
targetCellIndexPath = IndexPath (line: datePickerIndexPath!).row – 1, section: 0)
} else {
// external date picker: updates the date of the currently selected cell
targetCellIndexPath = self.myTableView.indexPathForSelectedRow!
}
leave cell = self.myTableView.cellForRow(at: targetCellIndexPath!)
leave targetDatePicker = sender
// update our data model
var itemData = dataArray [targetCellIndexPath !.row]
itemData [kDateKey] = targetDatePicker.date as AnyObject
dataArray [targetCellIndexPath !.row] = itemData.
// Update cell
Date row ?.detailTextLabel ?.text = dateFormatter.string (from: targetDatePicker.date)
}
Function @IBAction doneButtonTapped (sender: any object) {
leave targetedCellIndexPath = IndexPath (row:4, section: 0)
leave cell = myTableView.cellForRow(at: targetedCellIndexPath as IndexPath)
leave cellLabelText = cell ?.textLabel !.text
leave dateString = cell ?.detailTextLabel !.text!
print((cellLabelText!): (dateString!)
let myDateFormatter = DateFormatter()
myDateFormatter.dateFormat = MM/dd/yyyyy, h:mm a
myDateFormatter.timeZone = NSTimeZone.local
let providedDate = myDateFormatter.date (from: dateString!)! as date (from: dateString!)! (from: dateString!)! (date).
print (myDateFormatter.string (from: providedDate))
}
}
Video event
Below you will find video tutorials that show you how to extend UITableView with the built-in UIDatePicker or DateCell.
Online UIDatePicker/DateCell –User Interface Structure
Integrated UIDatePicker/DateCell – Added: Swift code
Configuring the UIDatePicker/DateCell Online
I hope this sample code has been useful to you!
On this page you will find more code examples in Swift : Examples of quick codes.
Related Tags: