Reputation:
How to set the date countdown in swiftui. I want to update decrease time each second. But I don't understand how to solve this problem?
struct TimerExample: View {
@State var currentTime = Date.now
@State var inputDate = "2022-12-03 12:20:09"
var body: some View {
Text("The time is: \(convertDateFormat(inputDate: inputDate))")
.padding()
.onAppear {
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) {
time in
currentTime = Date.now
}
}
}
func convertDateFormat(inputDate: String) -> String {
let olDateFormatter = DateFormatter()
olDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss" //"yyyy-MM-dd'T'HH:mm:ss"
let oldDate = olDateFormatter.date(from: inputDate)
let convertDateFormatter = DateFormatter()
convertDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
return convertDateFormatter.string(from: oldDate!)
}
}
Upvotes: 1
Views: 1493
Reputation: 206
This approach may be solution of your problem. please let me know it is working or not. if i understand your question then this is solution.
struct DateTimerView:View{
@State private var endDateText = "25-12-2027"
@State private var remainingTime = "Enter an end date"
@State private var timer: Timer?
var body: some View {
VStack {
TextField("Enter an end date", text: $endDateText, onCommit: startTimer)
.padding()
Text(remainingTime)
.padding()
}
.onDisappear(perform: stopTimer)
}
func startTimer() {
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy"
if let endDate = formatter.date(from: endDateText) {
let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
let currentDate = Date()
let calendar = Calendar.current
let difference = calendar.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: endDate)
if difference.day! > 0 {
remainingTime = "\(difference.day!) d \(difference.hour!) h \(difference.minute!) m \(difference.second!) s"
} else if difference.hour! > 0 {
remainingTime = "\(difference.hour!) h \(difference.minute!) m \(difference.second!) s"
} else if difference.minute! > 0 {
remainingTime = "\(difference.minute!) m \(difference.second!) s"
} else {
remainingTime = "\(difference.second!) s"
}
if currentDate >= endDate {
stopTimer()
}
}
self.timer = timer
} else {
remainingTime = "Invalid date format"
}
}
func stopTimer() {
timer?.invalidate()
timer = nil
}
}
Upvotes: -2
Reputation: 523
I Think You might what this to send OTP
here is the solution which will help you with resend OTP
struct OTPSample: View {
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
@State private var timeLimit: Int = 30
var body: some View {
ZStack {
Text(timeLimit > 0 ? "resend code in \(timeLimit)" : "resend code")
.foregroundColor(Color.ThemeGray)
.padding(15)
.setFont()
.onTapGesture {
if timeLimit < 1 {
print("resend OTP ")
}
}
}
.onReceive(timer) { _ in
if timeLimit > 0 {
timeLimit -= 1
}
}
}
}
Upvotes: -1
Reputation: 53181
You can achieve this using a TimelineView
and Text
with style: .timer
, as follows:
struct ContentView: View {
var body: some View {
TimerExample(endDate: .now + 500)
}
}
struct TimerExample: View {
let endDate: Date
var body: some View {
TimelineView(.periodic(from: .now, by: 1)) { context in
VStack {
Text("Time remaining:")
Text(endDate, style: .timer)
.font(.title)
Spacer()
}
.padding()
}
}
}
Upvotes: 7