I am using the UIPicker view for showing the Day, date and time as per the below screenshot:
I have implemented this by using the following code:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate,UIPickerViewDelegate,UIPickerViewDataSource {
@IBOutlet weak var txtDatePicker: UITextField!
@IBOutlet var dateLabel:UILabel!
let datePicker = UIPickerView()
var pickerDaysYear = [["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"],["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],["1AM", "2AM", "3AM", "4AM", "5AM", "6AM", "7AM", "8AM", "9AM", "10AM", "11AM", "12AM","1PM", "2PM", "3PM", "4PM", "5PM", "6PM", "7PM", "8PM", "9PM", "10PM", "11PM", "12PM",]];
override func viewDidLoad() {
super.viewDidLoad()
self.txtDatePicker.delegate = self
self.datePicker.dataSource = self
self.datePicker.delegate = self
self.txtDatePicker.inputView = self.datePicker
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.plain, target: self, action: #selector(self.doneButtonTapped))
toolBar.setItems([doneButton], animated: false)
self.txtDatePicker.inputAccessoryView = toolBar
}
@objc func doneButtonTapped(){
self.txtDatePicker.resignFirstResponder()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
view.endEditing(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//---------------- PickerView delegate Method --------------------------------//
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 3
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.pickerDaysYear[component].count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.pickerDaysYear[component][row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let days = pickerDaysYear[0][pickerView.selectedRow(inComponent: 0)]
let month = pickerDaysYear[1][pickerView.selectedRow(inComponent: 1)]
let time = pickerDaysYear[2][pickerView.selectedRow(inComponent: 2)]
txtDatePicker.text = days + " " + month + " " + time
}
}
I have achieved the desired output but the problem is i can still select invalid dates like "30 February" "31 April" etc ... So is there any way to prevent such invalid dates by being selected??. Right now the output is like :
In the Gregorian calendar, there is a leap year every four years. There are other rules to determine whether a given year is a leap year. Based on this web site, I have created the following class (MyDate.swift).
import Foundation
class MyDate: NSObject {
var year: Int
var month: Int
var day: Int
init(year: Int, month: Int, day: Int) {
self.year = year
self.month = month
self.day = day
}
func validateDate() -> Bool {
if month == 4 || month == 6 || month == 9 || month == 11 {
return (day == 30) ? true : false
}
else if month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 {
return (day == 31) ? true : false
}
else {
if isLeapYear(year: year) {
return (day < 30) ? true : false
} else {
return (day < 29) ? true : false
}
}
}
func isLeapYear(year: Int) -> Bool {
let mod4 = year % 4
if mod4 == 0 {
let mod100 = year % 100
if mod100 == 0 {
let mod400 = year % 400
if mod400 == 0 {
return true
} else {
return false
}
} else {
return true
}
} else {
return false
}
}
}
How to use MyDate
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
override func viewDidLoad() {
super.viewDidLoad()
let myDate = MyDate(year: 2020, month: 3, day: 32)
let bool = myDate.validateDate()
print(bool) // false
}
}
Instantiate MyDate with a given year, month and the day of the month. Then return a bool object with its validateDate method. So when the user selects a date, instantiate MyDate in the didSelectRow
method of UIPicker
. If validateDate returns false, set the day of the month to 1 or something.
txtDatePicker.selectRow(0, inComponent: 0, animated: false)