UIDatePicker minimumDate and maximumDate - ios

I'm trying to set a minimum and maximum date to limit the selection of the user, but it doesn't work:
override func viewDidLoad() {
let datePickerView : UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
tfDateNaissance.inputView = datePickerView
let gregorian: NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let currentDate: NSDate = NSDate()
let components: NSDateComponents = NSDateComponents()
components.year = -18
let minDate: NSDate = gregorian.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
components.year = -150
let maxDate: NSDate = gregorian.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
datePickerView.minimumDate = minDate
datePickerView.maximumDate = maxDate
datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
let pickerToolBar = UIToolbar()
pickerToolBar.barStyle = UIBarStyle.Black //you can change the style
pickerToolBar.translucent = true
pickerToolBar.tintColor = UIColor.whiteColor() // or other colours
pickerToolBar.sizeToFit()
let spaceButtonPicker = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
let cancelButtonPicker = UIBarButtonItem(title: "Ok", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelDatePicker:")
pickerToolBar.setItems([cancelButtonPicker, spaceButtonPicker], animated: false)
pickerToolBar.userInteractionEnabled = true
tfDateNaissance.inputAccessoryView = pickerToolBar
}
func datePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
// dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
//
// dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
tfDateNaissance.text = dateFormatter.stringFromDate(sender.date)
}
func cancelDatePicker(sender: UIBarButtonItem){
if tfProjet.isFirstResponder(){
tfProjet.resignFirstResponder()
} else if tfDateNaissance.isFirstResponder(){
tfDateNaissance.resignFirstResponder()
}
}
I found this code on stack overflow, I get no errors, but I can select 2200 as year for exemple. I think it's because it's an input view, so how to to ?

The minDate was later than the maxDate:
components.year = -150
let minDate: NSDate = gregorian.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
components.year = -18
let maxDate: NSDate = gregorian.dateByAddingComponents(components, toDate: currentDate, options: NSCalendarOptions(rawValue: 0))!
datePickerView.minimumDate = minDate
datePickerView.maximumDate = maxDate

Related

Forcing user not to put previous time on time pickers

I’m using time pickers and they work correctly as expected but the problem that i dont want to user to reserve a past time. when i click on the time pickers they doesn’t allow me to reserve past time but the problem is when i leave it opened and time continues it allow me to choose past time which is the time i click on it for example i opened time picker at 10:11 when i leave time picker opened and its 10:12 it allow me to choose 10:11 which is in past. im planning to show an error massage and force the time pickers to set time at current time if user chooses start time < current time. Hope its clear and this is my code if you can help
func createTimePicker() {
StartTimeTxt.textAlignment = .center
EndTimeTxt.textAlignment = .center
//tool bar
let toolbar = UIToolbar()
toolbar.sizeToFit()
//bar button(
let doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
toolbar.setItems([doneBtn], animated: true)
//assign tool bar
StartTimeTxt.inputAccessoryView = toolbar
EndTimeTxt.inputAccessoryView = toolbar
// assign time picker to the txt field
StartTimeTxt.inputView = StartTimePicker
EndTimeTxt.inputView = EndTimePicker
let calendar = Calendar.current
//First range
let startTime = Date()
let startRangeEnd = calendar.date(byAdding: DateComponents(minute: 30), to: startTime)!
let startRange = startTime...startRangeEnd
//Second range
let endTime = calendar.date(byAdding: DateComponents(minute: 1), to: startRangeEnd)!
let endRangeEnd = calendar.startOfDay(for: calendar.date(byAdding: DateComponents(day: 1), to: startTime)!)
let endRange = endTime...endRangeEnd
StartTimePicker.date = startTime
StartTimePicker.minimumDate = startTime
StartTimePicker.maximumDate = startRangeEnd
EndTimePicker.date = endTime
EndTimePicker.minimumDate = endTime
EndTimePicker.maximumDate = endRangeEnd
if #available(iOS 13.4, *) {
StartTimePicker.preferredDatePickerStyle = .wheels
EndTimePicker.preferredDatePickerStyle = .wheels
}
}
#objc func donePressed(){
// formatter
let calendar = Calendar.current
let startTime = Date()
let startRangeEnd = calendar.date(byAdding: DateComponents(minute: 30), to: startTime)!
let startRange = startTime...startRangeEnd
//Second range
let endTime = calendar.date(byAdding: DateComponents(minute: 1), to: startRangeEnd)!
let endRangeEnd = calendar.startOfDay(for: calendar.date(byAdding: DateComponents(day: 1), to: startTime)!)
let endRange = endTime...endRangeEnd
let formatter = DateFormatter()
formatter.dateStyle = .none
formatter.timeStyle = .short
StartTimeTxt.text = formatter.string(from: StartTimePicker.date)
self.view.endEditing(true)
EndTimeTxt.text = formatter.string(from: EndTimePicker.date)
self.view.endEditing(true)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "h:mm a"
startTimer = formatter.string(from: StartTimePicker.date)
endTimer = formatter.string(from: EndTimePicker.date)
// print(start, end)
// Format and print in 12h format
let hourAndMinutes = Calendar.current.dateComponents([.hour, .minute], from: StartTimePicker.date, to: EndTimePicker.date)
print(hourAndMinutes)
// Calculate price, the formula is just an example
var minutesPrice = 0
if ( hourAndMinutes.minute! == 0 ){
minutesPrice = 0
}
else {
minutesPrice = 15
}
let price = hourAndMinutes.hour! * 15 + minutesPrice
TotalPrice.text = String(price) + "SAR"
} ```

How to set a default date value in a inputView

I would like to set a default date value in inputView.
I have:
func createDatePickerDgeb1() {
datePickergeb.datePickerMode = .date
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressedgeb1))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
toolbar.setItems([spaceButton,doneButton], animated: false)
gebdatum.inputAccessoryView = toolbar
gebdatum.inputView = datePickergeb
}
The picker view shows me current date. Is possible that I can show for example the "01.01.1960" as a default?
// Create date components
var dateComponents = DateComponents()
dateComponents.year = 1960
dateComponents.month = 1
dateComponents.day = 1
// Create date from components
let userCalendar = Calendar.current // user calendar
let date = userCalendar.date(from: dateComponents)
// Set datePicker date
datePickergeb.setDate(date, animated: false)

How do I get the age after using a date picker?

I need to get the age after the datepicker has been used. How would I do this. I can currently get the datepicker to work.
#IBAction func datepickerobj(sender: UITextField) {
let datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = UIDatePickerMode.Date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePickerValueChanged(sender:UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.MediumStyle
dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle
dateofbirth.text = dateFormatter.stringFromDate(sender.date)
let myDOB = NSCalendar.currentCalendar().dateWithEra(1, year: 1970, month: 09, day: 10, hour: 0, minute: 0, second: 0, nanosecond: 0)!
let myAge = myDOB.age
}
Swift 4.1 / Xcode 9.4.1
func age(dateOfBirth: Date) -> Double {
var ageComponents: DateComponents = Calendar.current.dateComponents([.year], from: dateOfBirth, to: Date())
return Double(ageComponents.year!)
}
This will work fine for u
var birthday: NSDate = ..... //date that comes from date picker
var now: NSDate = NSDate()
var ageComponents: NSDateComponents = NSCalendar.currentCalendar().components(.Year, fromDate: birthday, toDate: now, options: 0)
var age: Int = ageComponents.year()
If u want to formate date you can use DateFormatter
Ex.
let usDateFormat = NSDateFormatter.dateFormatFromTemplate("MMddyyyy", options: 0, locale: NSLocale(localeIdentifier: "en-US"))
//usDateFormat now contains an optional string "MM/dd/yyyy".
let gbDateFormat = NSDateFormatter.dateFormatFromTemplate("MMddyyyy", options: 0, locale: NSLocale(localeIdentifier: "en-GB"))
//gbDateFormat now contains an optional string "dd/MM/yyyy"
formatter.dateFormat = usDateFormat
let usSwiftDayString = formatter.stringFromDate(swiftDay)
// usSwiftDayString now contains the string "06/02/2014".
formatter.dateFormat = gbDateFormat
let gbSwiftDayString = formatter.stringFromDate(swiftDay)
// gbSwiftDayString now contains the string "02/06/2014".
//may be it will help for u
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy"
let currentYear: Int = Int(formatter.stringFromDate(NSDate()))
let dobYear: Int = Int(formatter.stringFromDate(myDOB))
let age: Int = currentYear - dobYear
extension Date {
func age() -> Int {
return Int(Calendar.current.dateComponents([.year], from: self, to: Date()).year!)
}
}
An Date extension version, which let you call the method on any Date var. eg:
let calendar = NSCalendar.currentCalendar()
let components = calendar.components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day], fromDate: NSDate.init())
components.day = 31
components.month = 1
components.year = 1979
let date = calendar.dateFromComponents(components)
let years = date.age

How do I call the self.timer's changing value and indicate it at the label.text the ViewDidLoad's

I'm making a UILabel that indicates the value of the self.timer.
This is the code.
The problem is that I can't indicate the timeFormatter.stringFromDate(date_SSS) in the label.text.
Actually I also have a scrollView and a pageControl to scroll the label horizontally. But the main problem is at the UILabel and the self.timer.
import UIKit
class ViewController: UIViewController {
private var label: UILabel!
private var timer: NSTimer!
let intArray: String = ["12:00:00", "12:50:00", "15:30:00", "16:40:00"]
let i = 0
override func viewDidLoad() {
let timeFormatter = NSDateFormatter()
timeFormatter.dateFormat = "HH:mm:ss"
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update:", userInfo: nil, repeats: true)
self.timer.fire()
for (var i = 0; i < intArray.count; i++) {
let label: UILabel = UILabel(frame: CGRectMake(CGFloat(index) * 50,100,150,200)
label.cornerRadius = 20
label.text = timeFormatter.stringFromDate(date_SSS)
view.addSubView(label)
}
}
func dateFromString(date:String) -> NSDate? {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
calendar.locale = NSLocale(localeIdentifier: "en_US_POSIX")
calendar.timeZone = NSTimeZone(abbreviation: "JST")!
let begin = date.startIndex
guard let hour = Int(date.substringWithRange(begin..<begin.advancedBy(2))),
let minute = Int(date.substringWithRange(begin.advancedBy(3)..<begin.advancedBy(5))),
let second = Int(date.substringWithRange(begin.advancedBy(6)..<begin.advancedBy(8))) else{
return nil
}
return calendar.dateBySettingHour(hour, minute: minute, second: second, ofDate: NSDate(), options: [])
}
func update(timer: NSTimer) {
let timeFormatter: NSDateFormatter = NSDateFormatter()
timeFormatter.timeZone = NSTimeZone(name: "GMT")
timeFormatter.dateFormat = "HH:mm:ss"
let time = dateFromString(intArray[i])
let remain = time!.timeIntervalSinceDate(NSDate())
let date_SSS = NSDate(timeIntervalSince1970: remain)
}
}
well, you are not setting your label in your update method, so it's hard to see how it would change. maybe I don't understand your question.

How do you make UIDatePicker a 24 hour system

I have a UIDatePicker that is set to the hour the minutes then AM/PM. How do I make it so that it is set to the 24 hour system like in the UK? For example 1 would be 13 and there wouldn't be AM or PM.
var datePicker = UIDatePicker()
datePicker.datePickerMode = UIDatePickerMode.Time
datePicker.locale = NSLocale(localeIdentifier: "en_GB") // using Great Britain for this example
Using Swift 4
I have used the following the method to help me achieve a time-picker without AM / PM.
Note i am using TextField as Inputview
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
showTimePicker()
return true
}
func showTimePicker() {
timePicker.datePickerMode = .time
timePicker.locale = Locale(identifier: "en_GB") // Change to your locale
let toolbar = UIToolbar();
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneTimePicker));
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelTimePicker));
toolbar.setItems([doneButton,spaceButton,cancelButton], animated: false)
modifiedHoursTextField.inputAccessoryView = toolbar
modifiedHoursTextField.inputView = timePicker
}
#objc func doneTimePicker() {
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "HH:mm"
modifiedHoursTextField.text = timeFormatter.string(from: timePicker.date)
self.view.endEditing(true)
}
#objc func cancelTimePicker() {
self.view.endEditing(true)
}
Bonus to JAL's answer, if you also want to be able to pick "date", you can use something like below:
viewDidLoad:
deadlineTF.inputView = deadlineDatePicker
deadlineDatePicker.timeZone = NSTimeZone.local
deadlineDatePicker.datePickerMode = UIDatePickerMode.dateAndTime
deadlineDatePicker.locale = Locale(identifier: "tr_TR")
deadlineDatePicker.backgroundColor = UIColor.white
deadlineDatePicker.layer.cornerRadius = 5.0
deadlineDatePicker.layer.shadowOpacity = 0.5
deadlineDatePicker.addTarget(self, action: #selector(onDidChangeDate), for: .valueChanged)
.
The Function:
// called when the date picker called.
#objc func onDidChangeDate(sender: UIDatePicker){
// date format
let myDateFormatter: DateFormatter = DateFormatter()
myDateFormatter.dateFormat = "dd/MM/yyyy HH:mm"
// get the date string applied date format
let mySelectedDate = myDateFormatter.string(from: sender.date)
deadlineTF.text = mySelectedDate
}

Resources