iOS Swift 3 - UIDatePicker - ios

I have a UIDatePicker that shows the day, month and the year. But I don't know how to get those parameters.
So What is the best way to get the day, month and year from UIDatePicker using Swift 3?

UIDatePicker in Swift 3 and Swift 4 example.
In Swift 3 You can use
Create Simple Project of Single View Application in swift 3
Drag a text field & connect to viewController
Date picker look like image
ViewController code is bellow..
class ViewController: UIViewController {
//Text Field Connection
#IBOutlet weak var txtDatePicker: UITextField!
//Uidate picker
let datePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
//show date picker
showDatePicker()
}
func showDatePicker(){
//Formate Date
datePicker.datePickerMode = .date
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
//done button & cancel button
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.bordered, target: self, action: "donedatePicker")
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.bordered, target: self, action: "cancelDatePicker")
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
// add toolbar to textField
txtDatePicker.inputAccessoryView = toolbar
// add datepicker to textField
txtDatePicker.inputView = datePicker
}
func donedatePicker(){
//For date formate
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
txtDatePicker.text = formatter.string(from: datePicker.date)
//dismiss date picker dialog
self.view.endEditing(true)
}
func cancelDatePicker(){
//cancel button dismiss datepicker dialog
self.view.endEditing(true)
}
}
Full Source project is given to github. github Link:https://github.com/enamul95/DatePicker1
In Swift 4 or 5 you can use bellow code
class ViewController: UIViewController {
#IBOutlet weak var txtDatePicker: UITextField!
let datePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
showDatePicker()
}
func showDatePicker(){
//Formate Date
datePicker.datePickerMode = .date
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(donedatePicker));
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelDatePicker));
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
txtDatePicker.inputAccessoryView = toolbar
txtDatePicker.inputView = datePicker
}
#objc func donedatePicker(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
txtDatePicker.text = formatter.string(from: datePicker.date)
self.view.endEditing(true)
}
#objc func cancelDatePicker(){
self.view.endEditing(true)
}
}

In Swift 3 you can use DateComponents for that like this way.
First add action on datepicker for .valueChanged events.
datepicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)
Then get selected day, month and year using DateComponents in the action.
func dateChanged(_ sender: UIDatePicker) {
let components = Calendar.current.dateComponents([.year, .month, .day], from: sender.date)
if let day = components.day, let month = components.month, let year = components.year {
print("\(day) \(month) \(year)")
}
}

Suppose if you want to show datePicker on tapping textfield and when user select some date from it then it will automatically populate on your textfield .
#IBOutlet weak var dateTextField: UITextField!
let datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.date
dateTextField.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(ViewController.datePickerValueChanged), for: UIControlEvents.valueChanged)
// Make a dateFormatter in which format you would like to display the selected date in the textfield.
func datePickerValueChanged(sender:UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = DateFormatter.Style.medium
dateFormatter.timeStyle = DateFormatter.Style.none
dateTextField.text = dateFormatter.string(from: sender.date)
}
Here Sender.date which is the instance of UIDatePicker pick up the date from the datepicker and populate on your textfield.

Create IBOutlet of UIDatePicker and connect it properly then use below code to get day, month, year ect.
var comp = NSDateComponents()
#IBOutlet weak var datePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
datePicker.addTarget(self, action: Selector("datePickerChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerChanged(datePicker:UIDatePicker){
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
let cal = NSCalendar.currentCalendar()
comp = cal.components([.Era, .Day, .Month, .Year, .Hour, .Minute] , fromDate: datePicker.date)
// getting day, month, year ect
print ("Era:\(comp.era) Date:\(comp.day) Month:\(comp.month) Month:\(comp.year) Hours: \(comp.hour) Minuts:\(comp.minute)")
}

var picker = UIDatePicker()
picker = UIDatePicker()
textField.inputView = picker
picker.addTarget(self, action: #selector(ViewController.handleDatePicker), for: UIControlEvents.valueChanged)
picker.datePickerMode = .date
func handleDatePicker() {
var dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
textfield.text = dateFormatter.string(from: picker.date)
textfield.resignFirstResponder()
}

Swift 5 users can try this it works for me
import UIKit
class FreeCallsViewController: UIViewController {
#IBOutlet weak var dateTextField: UITextField!
let datepicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func calenderButtonPressed(_ sender: UIButton) {
self.createDatePicker()
}
func createDatePicker() {
let toolbar = UIToolbar()
toolbar.sizeToFit()
let donebtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donepressed))
toolbar.setItems([donebtn], animated: true)
dateTextField.inputAccessoryView = toolbar
dateTextField.inputView = datepicker
datepicker.datePickerMode = .date
}
#objc func donepressed() {
let dateformator = DateFormatter()
dateformator.dateStyle = .medium
dateformator.timeStyle = .none
dateTextField.text = dateformator.string(from: datepicker.date)
self.view.endEditing(true)
}
}

The problem can be solved in numerous way. If you are looking for a solution only using code:
class Foo: UIViewController {
// Lets create your picker - Can be IBOutlet too
lazy var datePicker: UIDatePicker = {
let picker = UIDatePicker()
picker.datePickerMode = .date
return picker
}()
override func viewDidLoad() {
super.viewDidLoad()
//Observe the value changes in datePickerValueChanged function for example
datePicker.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
}
func datePickerValueChanged(sender: UIDatePicker) {
// Function will be called every time picker changes it's value
// You can access to it the following way
print(sender.date)
}
}
The other way if you have your UIDatePicker in Interface Builder. You pretty much need to the same thing, like above, but i a slightly different way. Click on your UIDatePicker in Interface Builder:
You see the Value Changed option at the buttom. Now you grab and drag an IBAction to your viewController, and set up your connection like this:
This way you achive the same as the first example, because you end up with pretty much the same function:
#IBAction func datePickerValueChanged(sender: UIDatePicker) {
print(sender.date)
}

Swift 5.0+
I hope it will work for you, Enjoy!
import UIKit
protocol SKUIDatePickerDelegate:class {
func getDate(_ sKUIDatePicker:SKUIDatePicker, date:String)
func cancel(_ sKUIDatePicker:SKUIDatePicker)
}
class SKUIDatePicker:UIView {
private let datePicker = UIDatePicker()
private var dateFormate = "yyyy/mm/dd"
weak var delegate:SKUIDatePickerDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
// self.frame = UIScreen.main.bounds
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func showDatePicker(txtDatePicker:UITextField){
//Formate Date
datePicker.datePickerMode = .date
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(donedatePicker));
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelDatePicker));
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
txtDatePicker.inputAccessoryView = toolbar
txtDatePicker.inputView = datePicker
}
#objc func donedatePicker(){
let formatter = DateFormatter()
formatter.dateFormat = dateFormate
let result = formatter.string(from: datePicker.date)
self.delegate?.getDate(self, date: result)
}
#objc func cancelDatePicker(){
self.delegate?.cancel(self)
}
}
Usage
class ViewController: UIViewController,SKUIDatePickerDelegate {
//Text Field Connection
#IBOutlet weak var txtDatePicker: UITextField!
private var skUIdatePicker:SKUIdatePicker?
override func viewDidLoad() {
super.viewDidLoad()
skUIdatePicker = SKUIdatePicker()
skUIdatePicker.delegate = self
skUIdatePicker.showDatePicker(txtDatePicker:txtDatePicker)
}
func getDate(_ sKUIDatePicker:SKUIDatePicker, date:String) {
print(date)
self.view.endEditing(true)
}
func cancel(_ sKUIDatePicker:SKUIDatePicker){
self.view.endEditing(true)
}
}

Related

DatePicker passing data

I have a successful date picker and on the following page a stepper/number picker that allows users to select dates, and item quantities. In a new view, I would like to display all the previous information for them to review. I have a few methods in place but they don't seem to work. I am guessing it is because they aren't textFields, and some extra code is needed in order to ask the UIdatepicker and Stepper to pass the information. Take a look below please :)
Here is my date picker View Controller
import UIKit
class StoreDatesViewController: UIViewController {
#IBOutlet weak var nextButton: UIButton!
#IBOutlet weak var dropOff: UITextField!
#IBOutlet weak var pickUp: UITextField!
let datePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
showDatePicker()
}
override func viewWillAppear(_ animated: Bool) {
nextButton.isEnabled = true
}
func showDatePicker(){
//Format Date
datePicker.datePickerMode = .date
datePicker.preferredDatePickerStyle = .inline
datePicker.backgroundColor = UIColor(named: "yellow-2")
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
let toolbar2 = UIToolbar();
toolbar2.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(donedatePicker));
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelDatePicker));
let doneButton2 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(donedatePicker2));
let cancelButton2 = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelDatePicker2));
toolbar.setItems([doneButton,cancelButton], animated: false)
toolbar.tintColor = .white
toolbar.backgroundColor = .red
toolbar2.setItems([doneButton2,cancelButton2], animated: false)
toolbar2.tintColor = .white
dropOff.inputAccessoryView = toolbar
dropOff.inputView = datePicker
pickUp.inputAccessoryView = toolbar2
pickUp.inputView = datePicker
}
#objc func donedatePicker(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
dropOff.text = formatter.string(from: datePicker.date)
self.view.endEditing(true)
}
#objc func donedatePicker2(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
pickUp.text = formatter.string(from: datePicker.date)
self.view.endEditing(true)
}
#objc func cancelDatePicker(){
self.view.endEditing(true)
}
#objc func cancelDatePicker2(){
self.view.endEditing(true)
}
#IBAction func didTapNext() {
let dropOff = dropOff.text
let pickUp = pickUp.text
let storeDetailsVC = self.storyboard?.instantiateViewController(withIdentifier: "storeDetailsVC") as! storeDetailsViewController
storeDetailsVC.dropOff = dropOff!
storeDetailsVC.pickUp = pickUp!
}
}
Here is my number Pick View Controller
import UIKit
class StoreQuantityViewController: UIViewController{
#IBOutlet weak var numbers: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func stepper(_ sender: UIStepper) {
numbers.text = String(Int(sender.value))
}
#IBAction func next(_ sender: Any) {
let data2 = numbers.text
let storeDetailsVC = self.storyboard?.instantiateViewController(withIdentifier: "storeDetailsVC") as! storeDetailsViewController
storeDetailsVC.data2 = data2!
self.navigationController?.pushViewController(storeDetailsVC, animated: true)
}
}
```
You need to pass the information from text fields to Strings in the next View.
Solution 1:
override func viewDidLoad() {
super.viewDidLoad()
pickUp.text = currentDate // This you can create using the date formatter
dropOff.text = defaultDate // This is default date value you can set if needed
showDatePicker()
}
Solution 2:
#IBAction func didTapNext() {
//Apply validation here to check if its empty if no default value provided.
if dropOff.text.isEmpty {
//Show alert to user to select drof off date.
return
}
if pickUp.text.isEmpty {
//Show alert to user to select PickUp date.
return
}
let dropOff = dropOff.text
let pickUp = pickUp.text
let storeDetailsVC = self.storyboard?.instantiateViewController(withIdentifier: "storeDetailsVC") as! storeDetailsViewController
storeDetailsVC.dropOff = dropOff!
storeDetailsVC.pickUp = pickUp!
}

How to achieve the custom picker with Month, Date and time in iOS swift?

I am developing an app which requires to select the date from a picker view. But the picker view requires the Month,Date and time in the Picker view rows like in the attached image:
currently i am having the following code :
class ViewController: UIViewController {
#IBOutlet weak var txtDatePicker: UITextField!
let datePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
showDatePicker()
}
func showDatePicker(){
//Formate Date
datePicker.datePickerMode = .date
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(donedatePicker));
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelDatePicker));
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
txtDatePicker.inputAccessoryView = toolbar
txtDatePicker.inputView = datePicker
}
#objc func donedatePicker(){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
txtDatePicker.text = formatter.string(from: datePicker.date)
self.view.endEditing(true)
}
#objc func cancelDatePicker(){
self.view.endEditing(true)
}
}
But with this i am getting the output as :
How to add time to the UIPickerView ? Please suggest and help
Go to storyboard select your date picker view and in attribute inspector select date and time instead of Date.
And then you can select the date and time for the date picker.

Rx swift - Date picker freezes Rx swift View controller

Here is code i am using, i am new to rxswift. My question is simple when i tap on textfield date picker opens and it freezes my ViewController. I don't know what is the problem with UI in rxswift, this works well in only swift project. Your help is appreaciated pls help.
class ViewController: UIViewController {
//Text Field Connection
#IBOutlet weak var txtDatePicker: UITextField!
//Uidate picker
let datePicker = UIDatePicker()
override func viewDidLoad() {
super.viewDidLoad()
//show date picker
showDatePicker()
}
func showDatePicker(){
//Formate Date
datePicker.datePickerMode = .date
//ToolBar
let toolbar = UIToolbar();
toolbar.sizeToFit()
//done button & cancel button
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.bordered, target: self, action: "donedatePicker")
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.bordered, target: self, action: "cancelDatePicker")
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
// add toolbar to textField
txtDatePicker.inputAccessoryView = toolbar
// add datepicker to textField
txtDatePicker.inputView = datePicker
}
func donedatePicker(){
//For date formate
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
txtDatePicker.text = formatter.string(from: datePicker.date)
//dismiss date picker dialog
self.view.endEditing(true)
}
func cancelDatePicker(){
//cancel button dismiss datepicker dialog
self.view.endEditing(true)
}
}
a

How to pass the date picker (or just the date) to show the date on textfield in Swift?

I want show a date picker view on keyboard. I am doing this using UITextField extension.
My code:
extension UITextField {
//... other functions
func showDatePicker(){
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
let toolbar = UIToolbar();
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Pronto", style: UIBarButtonItemStyle.plain, target: self, action: #selector(UITextField.doneDatePicker(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancelar", style: UIBarButtonItemStyle.plain, target: self, action: #selector(UITextField.donePicker))
toolbar.setItems([cancelButton,spaceButton,doneButton], animated: false)
self.inputAccessoryView = toolbar
self.inputView = datePicker
}
#objc func doneDatePicker(_ datePicker: UIDatePicker){
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
self.text = formatter.string(from: datePicker.date)
self.endEditing(true)
}
}
My problem is when I tap "Pronto" button and the function doneDatePicker is executed. I need pass the UIDatePicker (or just the date) to show the date on textfield but I get this error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIBarButtonItem date]: unrecognized selector sent to instance 0x103488850'
How can I solve this?
You should simply subclass UITextField and declare your datepicker as a property of your UITextField, override didMoveToSuperview method and do the customisation there:
class DateField: UITextField {
var date: Date?
let datePicker = UIDatePicker()
let formatter = DateFormatter()
override func didMoveToSuperview() {
datePicker.datePickerMode = .date
formatter.dateStyle = .short
let toolbar = UIToolbar()
toolbar.sizeToFit()
let done = UIBarButtonItem(title: "Pronto", style: .plain, target: self, action: #selector(doneAction))
let space = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancel = UIBarButtonItem(title: "Cancelar", style: .plain, target: self, action: #selector(cancelAction))
toolbar.setItems([cancel,space,done], animated: false)
inputAccessoryView = toolbar
inputView = datePicker
}
#objc func cancelAction(_ sender: UIBarButtonItem) {
endEditing(true)
}
#objc func doneAction(_ sender: UIBarButtonItem) {
date = datePicker.date
text = formatter.string(from: datePicker.date)
endEditing(true)
}
}
It is not possible to pass extra parameters through selectors. Why you are passing date picker to
#objc func doneDatePicker(_ datePicker: UIDatePicker)
Replace
let datePicker = UIDatePicker()
with
var datePicker: UIDatePicker!
and put it as shared instance in a singleton class.
then access datePicker inside the function.

Show Present and Upcoming days on picker view

#IBOutlet weak var tvDueDate: UITextField!
#IBOutlet weak var dateText: UITextField!
var datePicker = UIDatePicker()
var dayPicker = UIDatePicker()
let dateFormatter = NSDateFormatter()
let timeFormatter = NSDateFormatter()
var date_time:String!
var timeAs_24Hour:String!
var selected_date:String!
var timeAs_12Hour:String!
override func viewDidLoad() {
super.viewDidLoad()
setupDatePicker()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func setupDatePicker() {
datePicker.datePickerMode = .Time
dayPicker.datePickerMode = .Date
let toolBar = UIToolbar()
toolBar.barStyle = .Default
toolBar.translucent = true
toolBar.tintColor = UIColor.blueColor()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(ViewController.doneClick))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .Plain, target: self, action: #selector(ViewController.cancelClick))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.userInteractionEnabled = true
tvDueDate.inputView = datePicker
tvDueDate.inputAccessoryView = toolBar
tvDueDate.tintColor = UIColor.clearColor()
dateText.inputView = dayPicker
dateText.inputAccessoryView = toolBar
dateText.tintColor = UIColor.clearColor()
}
func doneClick() {
dateFormatter.dateFormat = "yyyy-MM-dd"
timeFormatter.dateFormat = "hh:mm a"
dateFormatter.dateStyle = .MediumStyle
let selected_Final_Date = dateFormatter.stringFromDate(dayPicker.date)
let selected_Final_Time = timeFormatter.stringFromDate(datePicker.date)
self.dateText.text = selected_Final_Date.uppercaseString
self.tvDueDate.text = selected_Final_Time.uppercaseString
tvDueDate.resignFirstResponder()
dateText.resignFirstResponder()
}
func cancelClick() {
tvDueDate.resignFirstResponder()
dateText.resignFirstResponder()
}
I'm using Swift, and trying to create 2 picker views on 2 text field clicks. On the first text field, it's opening all days month year, on 2nd it's showing timing. I want to show present day and all upcoming days on 1st text field click, and on the 2nd text field, it should show time between 9 am to 6 pm only with a 30min difference like 9, 9:30, 10:00, 10:30, 11:00, 11:30.
You should use a UIDatePicker (or two, if you're determined to select the date in one field and the time in another)
They are designed for exactly this purpose.
They have settings they let you determine whether the user can pick dates, or dates and times, or just times. They also have settings they let you limit the range of dates or times that the user can pick. The Xcode documentation is a wonderful thing. You should try it.

Resources