UISegment Control - Set selected according to day (SWIFT) - ios

Like the title says, I'm trying to set the selected segment control according to day. My segment control includes the days of the week and i also have a date and time label. The proper day has to be selected when the view is open
I know i have to do something with:
segmentControl.selectedSegmentIndex = 0
I'm getting the date with:
showDate.text = "Date: " + DateFormatter.localizedString(from: Date(), dateStyle: DateFormatter.Style.medium, timeStyle: .none)
But I'm not sure how to set the selectedIndex to be dependent on date and show the appropriate day. I'm still new to swift and still learning, any help will be very much appreciated! Thanks

UISegmentedControl indexes start from 0. If you have all the days of the week in it its indexes start from 0 and end in 6.
You can get a day's index in weekdays using this
let day = Calendar.current.component(.weekday, from: Date())
this returns 1 for Sunday, 2 for Monday... 7 for Saturday
So you can assign selectedSegmentIndex as follows
if (2...6).contains(day) {
segmentControl.selectedSegmentIndex = day-2
} else {
segmentControl.selectedSegmentIndex = UISegmentedControlNoSegment
}

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!

Most concise fix for .weekday returning wrong day

I'm trying to get the current day of the week, this code is returning one day in the future. What is the most concise fix for this?
currentDay = DateFormatter().weekdaySymbols[Calendar.current.component(.weekday, from: Date())]
print(currentDay)
In iOS, the weekdaySymbols starts from Sunday to Saturday. It's an array so indexes range from 0 to 6
All you need to do is subtract the weekDay number by 1 to get the right day like below:
let weekDay = Calendar.current.component(.weekday, from: Date())
let currentDay = DateFormatter().weekdaySymbols[weekDay-1]
Also, note that when you try to fetch the weekDay number for Sunday from Calendar API it will return you 1
Please find the developer documentation snapshot for a reference

How to disable specific days in UIDatePicker

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!

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)}))

Using time to change theme with swift

I am trying to add in a feature that will change the background of that point twice a day. If it is 6:00 am then the app will show picture 1 and at 6:00 pm the picture will change to 2. If anyone knows how to do this please help.
You could use a timer to make the checks more or less frequent, but if you just want to set the image based on the time you could use something like this...
Swift 3
let hour = Calendar.current.component(.hour, from: Date())
if hour >= 6 || hour <= 17 {
print("use image one")
} else {
print("use image two")
}

Resources