DatePicker using Time-Interval in SwiftUI
I don't believe there is a modifier for this. However it's possible to "do it yourself" by using UIViewRepresentable to wrap a UIDatePicker:
The basic structure for this code is based on the Interfacing with UIKit tutorial.
struct MyDatePicker: UIViewRepresentable {
@Binding var selection: Date
let minuteInterval: Int
let displayedComponents: DatePickerComponents
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
func makeUIView(context: UIViewRepresentableContext<MyDatePicker>) -> UIDatePicker {
let picker = UIDatePicker()
// listen to changes coming from the date picker, and use them to update the state variable
picker.addTarget(context.coordinator, action: #selector(Coordinator.dateChanged), for: .valueChanged)
return picker
}
func updateUIView(_ picker: UIDatePicker, context: UIViewRepresentableContext<MyDatePicker>) {
picker.minuteInterval = minuteInterval
picker.date = selection
switch displayedComponents {
case .hourAndMinute:
picker.datePickerMode = .time
case .date:
picker.datePickerMode = .date
case [.hourAndMinute, .date]:
picker.datePickerMode = .dateAndTime
default:
break
}
}
class Coordinator {
let datePicker: MyDatePicker
init(_ datePicker: MyDatePicker) {
self.datePicker = datePicker
}
@objc func dateChanged(_ sender: UIDatePicker) {
datePicker.selection = sender.date
}
}
}
struct DatePickerDemo: View {
@State var wakeUp: Date = Date()
@State var minterval: Int = 1
var body: some View {
VStack {
Stepper(value: $minterval) {
Text("Minute interval: \(minterval)")
}
MyDatePicker(selection: $wakeUp, minuteInterval: minterval, displayedComponents: .hourAndMinute)
Text("\(wakeUp)")
}
}
}
struct DatePickerDemo_Previews: PreviewProvider {
static var previews: some View {
DatePickerDemo()
}
}
Specific times in a DatePicker()
You can't specify selected times in DatePicker.
But you could do something like this instead and and combine the values on commit:
struct ContentView: View {
@State private var date = Date()
@State private var time = "8:00"
var body: some View {
HStack {
DatePicker("Select", selection: $date, displayedComponents: .date)
.datePickerStyle(.compact)
.background(.background)
Picker("Time", selection: $time) {
Text("2:00").tag("2:00")
Text("8:00").tag("8:00")
Text("11:00").tag("11:00")
}
.pickerStyle(.wheel)
.frame(width: 100)
.zIndex(-1)
}
.padding()
}
}
Time Intervals SwiftUI
You have the wrong logic in if
, so "15:30" goes into ContentView2
. The correct logic may look like this:
if (hours == 12 && minutes >= 30) || (hours > 12 && hours < 15) {
ContentView2()
} else if (hours >= 15 && hours < 18) || (hours == 18 && minutes < 30) {
ContentView3()
} else {
ContentView1()
}
But I prefer using an other method: convert your values pair into a single value - in this case to day minutes, and use this value in switch
: in this case you can use ranges which looks more readable to me:
var body: some View {
switch hoursAndMinutesToMinutes(hours: dateComps.hour!, minutes: dateComps.minute!) {
case hoursAndMinutesToMinutes(hours: 12, minutes: 30)...hoursAndMinutesToMinutes(hours: 14, minutes: 59):
ContentView2()
case hoursAndMinutesToMinutes(hours: 15, minutes: 00)...hoursAndMinutesToMinutes(hours: 18, minutes: 30):
ContentView3()
default:
ContentView1()
}
}
func hoursAndMinutesToMinutes(hours: Int, minutes: Int) -> Int {
hours * 60 + minutes
}
How can I set countDownTimer mode in DatePicker on SwiftUI?
The only way to get the countdown behavior right now is by wrapping UIDatePicker
in a custom view.
Here is a simplified version of Ailton Vieira Pinto Filho's code using countDownDuration
.
import SwiftUI
struct DurationPicker: UIViewRepresentable {
@Binding var duration: TimeInterval
func makeUIView(context: Context) -> UIDatePicker {
let datePicker = UIDatePicker()
datePicker.datePickerMode = .countDownTimer
datePicker.addTarget(context.coordinator, action: #selector(Coordinator.updateDuration), for: .valueChanged)
return datePicker
}
func updateUIView(_ datePicker: UIDatePicker, context: Context) {
datePicker.countDownDuration = duration
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject {
let parent: DurationPicker
init(_ parent: DurationPicker) {
self.parent = parent
}
@objc func updateDuration(datePicker: UIDatePicker) {
parent.duration = datePicker.countDownDuration
}
}
}
UIDatePicker with 5 min interval get date on appear with interval
you could check the date and round it to your needs like this:
override func viewDidLoad() {
super.viewDidLoad()
let calendar = Calendar.current
var dateComponents = calendar.dateComponents([.month, .day, .year, .hour, .minute], from: datePicker.date)
guard var hour = dateComponents.hour, var minute = dateComponents.minute else {
print("something went wrong")
return
}
let intervalRemainder = minute % datePicker.minuteInterval
if intervalRemainder > 0 {
// need to correct the date
minute += datePicker.minuteInterval - intervalRemainder
if minute >= 60 {
hour += 1
minute -= 60
}
// update datecomponents
dateComponents.hour = hour
dateComponents.minute = minute
// get the corrected date
guard let roundedDate = calendar.date(from: dateComponents) else {
print("something went wrong")
return
}
// update the datepicker
datePicker.date = roundedDate
}
}
feel free to ask if anything is unclear!
Related Topics
Unsafemutablepointer in Swift as Replacement for Properly Sized C Array in Obj-C
How to Use Objective-C Enum in Swift
Sum Values of Properties Inside Array of Custom Objects Using Reduce
How to Make a Https Request to a Server in Swift
What Are Convenience Required Initializers in Swift
How to Bind a Variable to Multiple Alternatives in a Switch Statement
Swift Difference Between Final Var and Non-Final Var | Final Let and Non-Final Let
How to Set Countdowntimer Mode in Datepicker on Swiftui
Is It the Right Way Using '[Weak Self]' in Swift Closure
Xcode Incorrectly Reporting Swift Access Race Condition
How to Create a Static Class in Swift
How Does Anyobject Conform to Nsobjectprotocol
Calling Getsectiondata from Swift
How to Make Protocol Associated Type Require Protocol Inheritance and Not Protocol Adoption
Understanding the Userdefaults Register Method