How to disable specific days in UIDatePicker - ios

I have a UIDatePicker that should show only specific days, like all Sundays and Mondays, and disable all other dates, The user can select only Sunday and Monday from this week, next week, the week after, to, let's say, 2020.
Is that even possible with UIDatePicker, or even any custom control?

I would suggest you to use like this:
From below code you will get dates of all the Sundays from 2016-2018,
let cal = Calendar.current
// Get the date of 2 years ago today
let stopDate = cal.date(byAdding: .year, value: -2, to: Date())!
// We want to find dates that match on Sundays at midnight local time
var comps = DateComponents()
comps.weekday = 1 // Sunday
// Enumerate all of the dates
cal.enumerateDates(startingAfter: Date(), matching: comps, matchingPolicy: .previousTimePreservingSmallerComponents, repeatedTimePolicy: .first, direction: .backward) { (date, match, stop) in
if let date = date {
if date < stopDate {
stop = true // We've reached the end, exit the loop
} else {
print("\(date)") // do what you need with the date
}
}
}
The logic is simple. Make an array of this is in your required dateFormat and show that in pickerView which will eventually work as datePicker for you.
Hope this helps.

This is impossible. You have to create custom date picker based on UIPickerView.

There is a way to do it with just the UIDatePicker!
Lets say you have a minTime that is January 16 10:00AM
You would do something like this:
let picker = UIDatePicker()
picker.minimumDate = minTime
picker.maximumDate = minTime.changing(.hour, value: 23).changing(.minute, value: 59)
Then the picker will be stuck to that date.
Hope this helps someone!

Related

dateComponents() from... to in days shows from now to tomorrow as 0 days?

I have datecomponent objects that represent some time in the future. I want to calculate how many dates from now until that date. I'm also including representation of the dates simply as dates. What I'm finding is that when I am trying to show how many there are to a date that is 'tomorrow' it's showing 0. To my mind it should be showing 1. I can try a hacky way of just adding 1 to my count but I'm wondering is it because it's trying to round to the nearest 24 hours or something? If so how can I 'fix' it?
Here is my sample code:
let myPreviousRelevantDate = self.datePickerOutlet.date
let nextDate = Date(timeInterval: Double(86400 * (myDurationInDaysAsInt)), since: myPreviousRelevantDate!)
let daysToNextDate = Calendar.current.dateComponents([.day], from: Date(), to: nextDate).day!
What I'd like to avoid is the number of days to the target date changing during the day also - i.e. regardless of the timestamp of my target date - the number of days to that day remaining constant until midnight is reached.
If your intent is to calculate the number of days using a timeless calendrical calculation what you need is to use noon time. Note that not every day has 24 hours, you should always use calendar method to add days to a date:
extension Date {
var noon: Date {
Calendar(identifier: .iso8601)
.date(
bySettingHour: 12,
minute: 0,
second: 0,
of: self
)!
}
}
let daysToNextDate = Calendar.current.dateComponents([.day], from: Date().noon, to: nextDate.noon).day!

Swift Month year pickerView with last 12 months

I am having a filter on a tableView, that has a 'From' and 'To' Months selection.
Month selection, I mean, when I select Month, the datePicker should show Month Year only. And the list should contain last 12 months from today.
I looked at the default UIDatePicker but realized that it is not possible to get only Month-Year. (Reference answer from SO)
Further looking, I found this link that has a custom month-year picker but it shows future 15 years. And, upon selection of any row, nothing happens.
Can someone help me customize it to show last 12 months from today and fetch the result upon selection?
This is a simple example to get the last 12 months
var last12Months = [Date]()
let firstDayComponent = DateComponents(day: 1)
Calendar.current.enumerateDates(startingAfter: Date(),
matching: firstDayComponent,
matchingPolicy: .nextTime,
direction: .backward,
using: { (date, idx, stop) in
if let date = date {last12Months.append(date) }
if last12Months.count == 12 { stop = true }
})
print(last12Months)
let formatter = DateFormatter()
formatter.dateFormat = "MMMM yyyy"
print(last12Months.map({formatter.string(from: $0)}))

List of Days of this week

I need a list of days of the week (with the week starting on Monday) for a timecard list. Im not sure how to achieve this. I have tried some dateByAddingUnit and subtracting from there but it hasn't produced the results I want.
Any idea how to get a list of the dates? (i.e. Monday would be 3/28/16, Tuesday 3/29/16 and so on)
Edit: missed that you want a week to always start on a Monday
let gregorian = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let today = gregorian.startOfDayForDate(NSDate())
let startOfWeek: NSDate
if gregorian.component(.Weekday, fromDate: today) == 2 {
// Today is Monday
startOfWeek = today
} else {
// Find the last Monday prior to today
startOfWeek = gregorian.nextDateAfterDate(today, matchingUnit: .Weekday, value: 2, options: [.SearchBackwards, .MatchPreviousTimePreservingSmallerUnits])!
}

Swift 2.1 DatePicker setDate does not set date to current day and specified time

I am trying to set the minimum date to the current day on the date picker and then for the sake of user experience, set the time to 7pm or 19:00. For some reason it doesn't seem to be working. The minimum date setting works but the time doesn't get set. If I remove the minimum date line, the time gets set to 7pm, but strangely, the date gets set to Monday, Jan 1. Which isn't even this year.
Here's my code below:
datePicker.minimumDate = NSDate()
let calendar:NSCalendar = NSCalendar.currentCalendar()
let components = calendar.components([NSCalendarUnit.Hour, NSCalendarUnit.Minute], fromDate: NSDate())
components.hour = 19
components.minute = 00
datePicker.setDate(calendar.dateFromComponents(components)!, animated: true)
What am I doing wrong here?
Split that last line into:
let date = calendar.dateFromComponents(components)!
datePicker.setDate(date, animated: true)
Then look at the value of date. You'll find it is probably January 1, 2000 at the desired time.
Fix this by adding the year, month, and day components to:
let components = calendar.components([NSCalendarUnit.Hour, NSCalendarUnit.Minute], fromDate: NSDate())
In other words, you need:
let components = calendar.components([NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day, NSCalendarUnit.Hour, NSCalendarUnit.Minute], fromDate: NSDate())

NSDate from week number

I am trying to create a weekly recurring local notification using Swift. Notification is going to be set to first day of every week, and in 10:00. Ofcourse I don't want to set a notification for a past date, so I need to see if now it has passed first day of week 10:00. If not, I will create notification for today 10:00, else next week monday 10:00.
I created an extension to calculate week number for current date.
extension NSDate {
func weekOfYear() -> Int {
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(NSCalendarUnit.WeekOfYear, fromDate: self)
let weekOfYear = components.weekOfYear
return weekOfYear
}
}
I couldn't go any further than this. Any help is appreciated.
Regards.
There is an easier solution to your problem. You can use the nextDateAfterDate() method of NSCalendar:
let cal = NSCalendar.currentCalendar()
let comps = NSDateComponents()
comps.hour = 10
comps.weekday = cal.firstWeekday
let now = NSDate()
let fireDate = cal.nextDateAfterDate(now, matchingComponents: comps, options: [.MatchNextTimePreservingSmallerUnits])!
This gives the first date in the future which is at 10:00 on the first day of the week.

Resources