I have a DatePicker where the user selects time and date fields, the keyboard shows up first and then I have to click the textfield again for the Picker to appear. What I want is for the DatePicker to show up on the first try.
here is my code
#IBOutlet var dateField: UITextField! = UITextField()
#IBOutlet var timeField: UITextField! = UITextField()
#IBAction func userPickDate(sender: UITextField) {
var datePickerView : UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("handleDatePicker:"), forControlEvents: UIControlEvents.ValueChanged)
}
#IBAction func userPickTime(sender: UITextField) {
var datePickerView : UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Time
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("handleTimePicker:"), forControlEvents: UIControlEvents.ValueChanged)
}
func handleTimePicker(sender: UIDatePicker)
{
var timeFormatter = NSDateFormatter()
timeFormatter.timeStyle = .ShortStyle
timeField.text = timeFormatter.stringFromDate(sender.date)
}
func handleDatePicker(sender: UIDatePicker) {
var timeFormatter = NSDateFormatter()
timeFormatter.dateStyle = .MediumStyle
//timeFormatter.timeStyle = .ShortStyle
dateField.text = timeFormatter.stringFromDate(sender.date)
}
Discard the last answer. I understood whAT you are doing. Here is what I found: Placing the declaration of the UPickerView objects in the scope of the class rather than localized to the handler seemed to work. Here is the code. Note the addition of the resignFirstResponder().
import UIKit
class ViewController: UIViewController {
var datePickerView : UIDatePicker = UIDatePicker()
var timePickerView : UIDatePicker = UIDatePicker()
#IBOutlet weak var dateField: UITextField!
#IBOutlet weak var timeField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
datePickerView.datePickerMode = UIDatePickerMode.Date
dateField.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("handleDatePicker:"), forControlEvents: UIControlEvents.ValueChanged)
handleDatePicker(datePickerView)
timePickerView.datePickerMode = UIDatePickerMode.Time
timeField.inputView = timePickerView
timePickerView.addTarget(self, action: Selector("handleTimePicker:"), forControlEvents: UIControlEvents.ValueChanged)
handleTimePicker(timePickerView)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func handleDatePicker(sender: UIDatePicker) {
var dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
//timeFormatter.timeStyle = .ShortStyle
dateField.text = dateFormatter.stringFromDate(sender.date)
dateField.resignFirstResponder()
}
func handleTimePicker(sender: UIDatePicker) {
var timeFormatter = NSDateFormatter()
timeFormatter.timeStyle = .ShortStyle
timeField.text = timeFormatter.stringFromDate(sender.date)
timeField.resignFirstResponder()
}
}
You need to place an action on your textField as such:
#IBAction func userDOBSelectedAction(sender: UITextField) {
userDOBTextField.resignFirstResponder()
}
This is an updated version of Syed's answer for Swift 2.2 & includes some formatting updates.
import UIKit
class ViewController: UIViewController {
var datePickerView : UIDatePicker = UIDatePicker()
var timePickerView : UIDatePicker = UIDatePicker()
#IBOutlet weak var dateField: UITextField!
#IBOutlet weak var timeField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
datePickerView.datePickerMode = .Date
dateField.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(ViewController.handleDatePicker(_:)), forControlEvents: .ValueChanged)
handleDatePicker(datePickerView)
timePickerView.datePickerMode = .Time
timeField.inputView = timePickerView
timePickerView.addTarget(self, action: #selector(ViewController.handleTimePicker(_:)), forControlEvents: .ValueChanged)
handleTimePicker(timePickerView)
}
func handleDatePicker(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
dateField.text = dateFormatter.stringFromDate(sender.date)
dateField.resignFirstResponder()
}
func handleTimePicker(sender: UIDatePicker) {
let timeFormatter = NSDateFormatter()
timeFormatter.timeStyle = .ShortStyle
timeField.text = timeFormatter.stringFromDate(sender.date)
timeField.resignFirstResponder()
}
}
Related
First let me state all the other code you see works as desired except for the UIDatePicker. Right now when I click on the dateTextField the UIDatePicker shows up and I can select a date but when I click the Done button the Date selected is not in the UITextField assigned to it.
One area that may be a place to focus is the doneClicked function. When I initially created it I did not have the (#objc) in front of it and it gave me an error.
/Argument of '#selector' refers to instance method doneClicked() that is not exposed to Objective-C/
So I added (#objc) and the error went away but as stated above the date selected from the UIDatePicker is not being saved in the UITextField.
If you would please explain and show where my code is wrong and how to fix it.
Any help is greatly appreciated in this matter thank you very much.
import Foundation
import UIKit
import Firebase
import FirebaseUI
class TrainViewController: UIViewController{
#IBOutlet weak var trainField: UITextField!
#IBOutlet weak var locationField: UITextField!
#IBOutlet weak var engineField: UITextField!
#IBOutlet weak var dateTextField: UITextField!
let datePicker = UIDatePicker()
#IBAction func saveButton(_ sender: UIButton) {
self.saveText()
trainField.text?.removeAll()
locationField.text?.removeAll()
engineField.text?.removeAll()
dateTextField.text?.removeAll()
self.view.endEditing(true)
}
override func viewDidLoad() {
super.viewDidLoad()
createDatePicker()
}
func saveText() {
let trainText = self.trainField.text!
let locationText = self.locationField.text!
let engineText = self.engineField.text!
let dateStart = self.dateTextField.text!
let db = Firestore.firestore()
let dict = ["train_text": trainText,
"location_text": locationText,
"engine_text": engineText,
"dateStart_text": dateStart]
db.collection("users").addDocument(data: dict)
}
func createDatePicker(){
//format the display of our datepicker
datePicker.datePickerMode = .date
//assign date picker to our textfield
dateTextField.inputView = datePicker
//create a toolbar
let toolbar = UIToolbar()
toolbar.sizeToFit()
//add a done button on this toolbar
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(doneClicked))
toolbar.setItems([doneButton], animated: true)
dateTextField.inputAccessoryView = toolbar
}
#objc func doneClicked(){
//format the date display in textfield
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
}
}
extension TrainViewController : UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
you are not assigning the date in textFiled.
Like : dateTextField.text = dateString
in doneClicked click, get the date form datePicker and assign to dateTextField.
Code:
#objc func doneClicked(){
//format the date display in textfield
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .none
let dateString = dateFormatter.stringFromDate(datePicker.date)
print(dateString)
dateTextField.text = dateString
}
I'm trying to update two buttons with datepicker. Button startDate et endDate. I don't how can I update these butttons with differents datepicker.
Maybe with handler ?
user story : the user click on startDat datepicker is displaying, user choose any date or time, then click on endDate and same action.
EDIT:
class ViewController: UIViewController {
#IBOutlet weak var dateTextField: UITextField!
#IBOutlet weak var dateTextLabel: UILabel!
var whoTriggeredPickerView: UIButton?
#IBOutlet weak var startDateTextButton : UIButton!
#IBOutlet weak var endDateTextButton : UIButton!
#IBOutlet weak var datePick : UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func donePressed(_ sender: UIBarButtonItem) {
dateTextField.resignFirstResponder()
dateTextLabel.resignFirstResponder()
startDateTextButton.resignFirstResponder()
endDateTextButton.resignFirstResponder()
}
func donePressedButton(_ sender :UIButton){
startDateTextButton.resignFirstResponder()
endDateTextButton.resignFirstResponder()
}
func tappedToolBarBtn(_ sender: UIBarButtonItem) {
let dateformatter = DateFormatter()
startDateTextButton.setTitle(dateformatter.string(from: Date()), for: .normal)
endDateTextButton.setTitle(dateformatter.string(from: Date()), for: .normal)
startDateTextButton.resignFirstResponder()
endDateTextButton.resignFirstResponder()
}
func closeDatePicker(){
self.view.endEditing(true)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
closeDatePicker()
}
#IBAction func BtnClicked(sender: UIButton) {
let datePickerView: UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.date
//sender.inputView = datePickerView
self.view.addSubview(datePickerView)
datePickerView.addTarget(self, action: #selector(ViewController.datePickerValueChanged), for: UIControlEvents.valueChanged)
self.whoTriggeredPickerView = sender
}
func datePickerValueChanged(_ sender: UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = DateFormatter.Style.medium
dateFormatter.timeStyle = DateFormatter.Style.none
//dateTextField.text = dateFormatter.string(from: sender.date)
if self.whoTriggeredPickerView == startDateTextButton {
// set startDateBtn title
startDateTextButton.setTitle(dateFormatter.string(from: Date()), for: .normal)
}else if self.whoTriggeredPickerView == endDateTextButton {
// set endDateBtn title
endDateTextButton.setTitle(dateFormatter.string(from: Date()), for: .normal)
}
}
}
For your question:
You can create a tmp variable to record picker is triggered by which button. Then you can decide which button's title you want to set.
//In your view controller:
var whoTriggeredPickerView: UIButton?
//In your BtnClicked function:
self.whoTriggeredPickerView = sender
//Then in datePickerValueChanged function:
if self.whoTriggeredPickerView == StartDateButton {
// set startDateBtn title
}else if self.whoTriggerPickerView == endDateButton {
// set endDateBtn title
}
Some suggestions:
always lowercase the instance name, you are using DatePick as the instance name of UIDatePicker, instead, you should name it as datePicker; for function names as well.
for your case you can use two textfields instead of buttons.
let datePicker = UIDatePicker()
datePicker.addTarget(self, action: #selector(dateChanged), for: .valueChanged)
startDateTextField.inputView = datePicler
endDateTextField.inputView = datePicker
I'm making a To-Do app and I want the value of the date picker as saved by the user into a variable so that I can print that variable in a tableView.
This is my datePicker code:
#IBOutlet weak var datePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
datePicker.minimumDate = Date()
datePicker.locale = Locale.current
datePicker.setValue(UIColor.gray, forKeyPath: "textColor")
}
You can add a specific target to you Picker in order to get a new value.
For example :
#IBOutlet weak var datePicker: UIDatePicker!
var selectedDate : Date?
override func viewDidLoad() {
super.viewDidLoad()
self.datePicker.addTarget(self, action: #selector(self.storeSelectedRow), for: UIControlEvents.valueChanged)
}
func storeSelectedRow(){
self.selectedDate = self.datePicker.date
}
OR
With the storyboard:
As you add you pickerView as a #IBOutlet you can add a #IBAction to your view controller and then get the date of your picker and store it to a variable.
Please see this example that pass the Picker Value to another ViewController
https://drive.google.com/file/d/0B2RAeG6eqtvCbWp1VE5IZ0E2Vkk/view?usp=sharing
Add follow code in viewDidLoad.
datePicker.addTarget(self, action: "dateChanged:",
forControlEvents: UIControlEvents.ValueChanged)
Then get value in func dateChanged.
func dateChanged(datePicker : UIDatePicker){
let formatter = NSDateFormatter()
//formatter
formatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
print(formatter.stringFromDate(datePicker.date))
//there you get your label first
//let label = ...
label.text = formatter.stringFromDate(datePicker.date)
}
I have making and order app I have take an outlet named: selectedDate and I want to retrieve the selected date to a variable. What should I place in View did load.
#IBOutlet weak var selectedDate: UIDatePicker!
func datePickerChanged(selectedDate:UIDatePicker) {
var dateFormatter = DateFormatter()
dateFormatter.dateStyle = DateFormatter.Style.FullStyle
dateFormatter.timeStyle = DateFormatter.Style.FulltStyle
var strDate = dateFormatter.string(from: selectedDate.date)
}
class ViewController: UIViewController {
#IBOutlet weak var datePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func datePickerChanged(sender: UIDatePicker) {
print("print \(sender.date)")
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM dd, YYYY"
let somedateString = dateFormatter.stringFromDate(sender.date)
print(somedateString) // "somedateString" is your string date
}
}
You have to create a IBAction for datePicker and name it as “datePickerChanged” , just like you create outlet of object. Choose connection type "Action" when you are dragging object to Viewcontroller.
func datePickerChanged(_:UIDatePicker) is a target function.
Did you set the target correctly ?
// Precise that our controller implement the delegate
class MyViewController: UIViewController {
...
#IBOutlet weak var selectedDate: UIDatePicker!
...
override func viewDidLoad() {
super.viewDidLoad()
...
selectedDate.addTarget(self, action: #selector(datePickerChanged(_:)), forControlEvents: .valueChanged) // We register the target function
}
...
// We implement that function
func datePickerChanged(sender:UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
dateFormatter.timeStyle = .full
let strDate = dateFormatter.string(from: sender.date)
print(strDate)
}
}
I'm trying to let the user pick a date and let it display in a text field. I've found so many answers online but none of them seem to work. I don't if they are outdated. I'm getting an error on "datePickerView.addTarget" in the selector part. When I run the app, I tap on the text field and the keyboard appears which is what I want. But the app crashes as soon as I change the date.
Any help would be really appreciated!
#IBAction func dateFieldEditing(sender: UITextField) {
let datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action:Selector("handleDatePicker"),forControlEvents: UIControlEvents.ValueChanged)
}
func handleDatePicker (sender: UIDatePicker){
let formatter = NSDateFormatter()
formatter.dateStyle = .LongStyle
dateField.text = formatter.stringFromDate(sender.date)
}
The following works, assuming that you have a UITextField and UIDatePicker bound as IBOutlets via Interface Builder. Setting sender.inputView was unnecessary.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var datePicker: UIDatePicker?
#IBOutlet weak var textField: UITextField?
func handleDatePicker (sender: UIDatePicker) {
let formatter = NSDateFormatter()
formatter.dateStyle = .LongStyle
textField!.text = formatter.stringFromDate(sender.date)
}
override func viewDidLoad() {
super.viewDidLoad()
self.datePicker!.datePickerMode = UIDatePickerMode.Date
datePicker!.addTarget(self, action:#selector(handleDatePicker(_:)), forControlEvents: UIControlEvents.ValueChanged)
}
}