Swift changed DatePicker Date to Firebase - swift

In my app, you click a button and the activity name and activity location is added to Firebase. I also want to add a selected time that you will be doing the activity to Firebase as well. To do this, I have created a DatePicker to pop up upon clicking the button, I have also managed to convert this to a string and upload to Firebase.
The issue I am having is the time that it uploads to Firebase is always the current time, am I right in saying I need to add an action to the DatePicker which will allow the selected time to be uploaded? If so how do I go about this?
func handleAddAgenda(){
var datePicker: UIDatePicker = UIDatePicker()
datePicker.datePickerMode = UIDatePickerMode.DateAndTime
//datePicker.addTarget(self, action: #selector(dateChanged), forControlEvents: UIControlEvents.ValueChanged)
datePicker.frame = CGRectMake(0, 0, 250, 460)
datePicker.backgroundColor = UIColor.whiteColor()
addSubview(datePicker)
class ActDate: NSObject {
var date: String?
}
var actDate: ActDate?
if actDate == nil {
actDate = ActDate()
}
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "hh:mm a"
actDate?.date = dateFormatter.stringFromDate(datePicker.date)
print(datePicker.date)
let userID = FIRAuth.auth()?.currentUser?.uid
let ref = FIRDatabase.database().reference().child("users").child(userID!).child("Agenda")
let childRef = ref.childByAutoId()
let values = ["activity": activityName.text!, "location": distance.text!, "date": actDate!.date!]
childRef.updateChildValues(values)
}

Yes, you need to add some action method to update the values when the datePicker date is selected. This will only work of course if you make the date picker a property of the whole class in order to grab the datePicker.date in the new method.
Something like this in viewDidLoad:
datePicker.datePickerMode = UIDatePickerMode.DateAndTime
datePicker.frame = CGRectMake(0, 0, 250, 460)
datePicker.backgroundColor = UIColor.whiteColor()
myDatePicker.addTarget(self, action: #selector(dateChanged), for: .valueChanged)
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "hh:mm a"
actDate?.date = dateFormatter.stringFromDate(datePicker.date)
Then you can have your handleAgenda simplified to this:
func handleAddAgenda(){
addSubview(datePicker)
print(datePicker.date)
}
And finally make the FireBase updates in the method:
func dateChanged() {
if let userID = FIRAuth.auth()?.currentUser?.uid {
let ref = FIRDatabase.database().reference().child("users").child(userID).child("Agenda")
let childRef = ref.childByAutoId()
if let activityName = activityName.text, let distance = distance.text, let date = datePicker.date {
let values = ["activity": activityName, "location": distance, "date": date]
childRef.updateChildValues(values)
}
}
}

Related

How to send Date and Time separately to backend in swift?

fromDateLabel.text getting date and time from datepicker.. which i need to send date and time seperatedly to backend
when i do DateFormatter date is coming correctly but in time, only two digit values are working means time taking 10, 11, 12 O'Clocks. if i take 1,2,3,4,5 its not working
code: here single digit time not working
var fromDateArr = fromDateLabel.text!.components(separatedBy: ",")
fromDate = fromDateArr[0]
fromTime = fromDateArr[1].replacingOccurrences(of: " ", with: "")
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "MM/dd/yy"
let showDateFrom = inputFormatter.date(from: fromDate)
inputFormatter.dateFormat = "dd-MM-yyyy"
formateFromdate = inputFormatter.string(from: showDateFrom!)
print("formate from date \(formateFromdate)")
if i formate date and time like below nothing works
let fromDate = fromDateLabel.text!
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "MM/dd/yy, hh:mm:ssa"
guard let showDateFrom = inputFormatter.date(from: fromDate) else { return }
inputFormatter.dateFormat = "MM/dd/yyyy" // -> to get date only
formateFromdate = inputFormatter.string(from: showDateFrom)
print("from date: ", formateFromdate)
inputFormatter.dateFormat = "hh:mm a" // -> to get time only
formateFromTime = inputFormatter.string(from: showDateFrom)
print("from time")
How to send date and time separately to backend.. with 1 to 12hrs time
NOTE: if its 8 o clock then the out put time should be 08:15, not 8:15.. thats the issue.. please help me with code
Design
import UIKit
class ViewController: UIViewController{
#IBOutlet weak var txtdate: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.txtdate.setInputViewDatePicker(target: self, selector: #selector(tapDone)) //1
}
#objc func tapDone() {
if let datePicker = self.txtdate.inputView as? UIDatePicker {
let dateformatter = DateFormatter()
dateformatter.dateFormat = "MM/dd/yy, hh:mm a"
self.txtdate.text = dateformatter.string(from: datePicker.date)
}
self.txtdate.resignFirstResponder()
}
#IBAction func showClk(_ sender: Any) {
let fromDate = txtdate.text!
print(fromDate)
let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "MM/dd/yy, hh:mm a"
guard let showDateFrom = inputFormatter.date(from: fromDate) else { return }
inputFormatter.dateFormat = "MM/dd/yyyy" // -> to get date only
let formateFromdate = inputFormatter.string(from: showDateFrom)
print("from date: ", formateFromdate)
inputFormatter.dateFormat = "hh:mm a" // -> to get time only
let formateFromTime = inputFormatter.string(from: showDateFrom)
print("from time" ,formateFromTime)
}
}
extension UITextField {
func setInputViewDatePicker(target: Any, selector: Selector) {
// Create a UIDatePicker object and assign to inputView
let screenWidth = UIScreen.main.bounds.width
let datePicker = UIDatePicker(frame: CGRect(x: 0, y: 0, width: screenWidth, height: 216))//1
datePicker.datePickerMode = .date
self.inputView = datePicker
// Create a toolbar and assign it to inputAccessoryView
let toolBar = UIToolbar(frame: CGRect(x: 0.0, y: 0.0, width: screenWidth, height: 44.0))
let flexible = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancel = UIBarButtonItem(title: "Cancel", style: .plain, target: nil, action: #selector(tapCancel))
let barButton = UIBarButtonItem(title: "Done", style: .plain, target: target, action: selector)
toolBar.setItems([cancel, flexible, barButton], animated: false)
self.inputAccessoryView = toolBar
}
#objc func tapCancel() {
self.resignFirstResponder()
}
}

How to use the time of datePicker only after clicking at Save Button

I am trying to use the hour and minutes of the date picker and add a notification with it. It is working now when the user immeadiatly chooses the hour and minutes from the DatePicker. My problem is that I only wanna create the notification when the user clicks at a Button Save, not when changing the value of the picker. How do I do that?
#objc func printMedHour(sender: UIDatePicker) {
let date = DateFormatter()
date.timeStyle = .short
let dateString = date.string(from: datePicker.date)
let dateAsString = (dateString)//"1:15 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "h:mm a"
let dates = dateFormatter.date(from: dateAsString)
dateFormatter.dateFormat = "HH:mm"
let Date24 = dateFormatter.string(from: dates!)
//print(dateString)
print(Date24)
let hour = Date24.prefix(2)
let minutes = Date24.suffix(2)
print(hour)
print(minutes)
let content = UNMutableNotificationContent()
content.title = "Time to take your med"
content.body = "Don't forget"
var dateComponent = DateComponents()
dateComponent.calendar = Calendar.current
let hourString = (hour)
let hourInt = Int(hourString)
print(hourInt)
let minuteString = (minutes)
let minuteInt = Int(minuteString)
print(minuteInt)
//dateComponent.weekday = 7 //Saturday
dateComponent.hour = (hourInt) as? Int //Hour
dateComponent.minute = (minuteInt) as! Int //Minute
//Trigger:
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponent, repeats: true)
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.add(request, withCompletionHandler: {(error) in
if error != nil {
print("Error")
}
})
self.reminderTextField.text = dateString
view.endEditing(true)
}
My Button is the following:
let saveButton: UIButton = {
let button = UIButton()
button.setTitle("Save", for: .normal)
button.backgroundColor = UIColor.rgb(red: 40, green: 40, blue: 40)
button.contentMode = .center
button.titleLabel?.textColor = .white
button.titleLabel?.font = UIFont(name: "Verdana", size: 20)
button.addTarget(self, action: #selector(saveUserSettings), for: .touchUpInside)
button.isOpaque = true
button.layer.opacity = 0.9
button.addTarget(self, action: #selector(AddMedViewController.printMedHour(sender:)), for: UIControl.Event.valueChanged)
return button
}()
When adding the target to the date picker, the notification is not created.
What I am doing wrong?
Thanks!

myLabel display the wrong name (UIDatePicker)

I have a problem, my label displays the wrong month name after selected from DatePicker.
img app
Code:
let myDatePicker: UIDatePicker = {
let pv = UIDatePicker()
pv.datePickerMode = .date
pv.locale = Locale(identifier: "de_DE")
pv.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
return pv
}()
#objc func datePickerValueChanged(datePicker: UIDatePicker) {
let format = "dd MMM, yyyy"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
let dateValue = dateFormatter.string(from: datePicker.date)
myLabel.text = dateValue
}
let myLabel: UILabel = {
let label = UILabel()
return label
}()
P.S I have an additional question how to set the language of months in DatePicker automatically with regional settings?
I tried (inside myDatePicker) : pv.locale = .current
First question:
You need to "localize" your dateFormatter, using
dateFormatter.locale = datePicker.locale
in your datePickerValueChanged
Second question:
You want to retrieve the correct month names as retrieved from the iPhone settings
Use Locale.autoupdatingCurrent instead of Locale(identifier: "de_DE")
. This gets the user preferred current locale, automatically up-to-date.

DateFormatter Swift 3

So I am creating a contact phonebook app and I am trying to get the keyboard to display as a DateTimePicker.
I have gotten the keyboard to work after some time but I can't seem to get the formatter working correctly.
#IBOutlet weak var datetxt: UITextField!
var datepicker = UIDatePicker()
func createdatepicker() {
datepicker.datePickerMode = .date
let toolbar = UIToolbar()
toolbar.sizeToFit()
let donebutton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneac))
toolbar.setItems([donebutton], animated: true)
datetxt.inputAccessoryView = toolbar
datetxt.inputView = datepicker
}
func doneac() {
let Date = DateFormatter()
Date.dateStyle = .short
//Date.string(from: String)
datetxt.text = "\(datepicker.date)"
self.view.endEditing(true)
}
When I run the app it selects the date but, it also shows the time in the text field.
You're not using your DateFormatter. The datetxt.text = "\(datepicker.date)" simply sets the text to the description of the date picker's date (which includes date and time). But you're not using your formatter at all.
And, by the way, I wouldn't use Date for the name of the date formatter. One would generally use formatter or dateFormatter. Date only invites confusion with the Swift type of the same name.
Thus, you might do:
let formatter = DateFormatter()
formatter.dateStyle = .short
datetxt.text = formatter.string(from: datepicker.date)
here you can make use of formatter you had not showed any date formatter you used
//here is current date
let date = Date()
//formatter to return value as 21-11-2017
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
//Date Output
let result = formatter.string(from: date)
//second formatter to return time format like 2:31 Am
let formatter1 = DateFormatter()
formatter1.dateFormat = "h:mm a"
//Time Output
let result1 = formatter1.string(from: date)
//set values for example using label for reference
DateLabel.text = result
TimeLabel.text = result1
//actual output is as Follows:
DateLabel = 21-11-2107
TimeLabel = 9:54 AM

how to restrict in datepicker current date to next 15days in swift 2.0

I am trying this code but it is not working.
thanks to all.
I am using uidatepicker with select minimumDate. but require current date with additional 15 days in datepicker swift 2.0.
override func viewDidLoad() {
let datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.minimumDate = datePickerView.date
//datePickerView.maximumDate = datePickerView.date
datePickerView.addTarget(self, action: #selector(BookAppointmentView.datePickerValueChanged(_:)), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChanged(sender:UIDatePicker)->NSDate {
let baseDate:NSDate = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
DatePickerField.text = dateFormatter.stringFromDate(sender.date)
print("date of bookAppointment\(DatePickerField.text!)")
return newDate!
}
There are multiple ways to accomplish this.
dateByAddingTimeInterval is one, in which you add time in seconds:
datepickerView.minimumDate = NSDate() // current date
datepickerView.maximumDate = NSDate().dateByAddingTimeInterval(1296000) // date + 15 days
You can also do:
datepickerView.minimumDate = NSDate() // current date
let maxDateComponent = NSDateComponents()
maxDateComponent.day = //days you want to add
datePickerView.maximumDate = NSCalendar.currentCalendar().dateByAddingComponents(maxDateComponent, toDate: NSDate(), options: NSCalendarOptions.init(rawValue: 0))
In which you add the time in days.
I hope this extension method helps
extension NSDate {
func dateByAddingDays(days:Int) -> NSDate? {
let c:NSDateComponents = NSDateComponents()
c.day = days;
return NSCalendar.currentCalendar().dateByAddingComponents(c, toDate: self, options: [])
}
}
this code is not tested. but i have used dateByAddingComponents in some cases