How to Update Text Using Timer in Swiftui

How to update text using timer in SwiftUI

i have managed to update text using alert.

i have declared date as State so whenever date is changed using alert text will also get updated.

struct CurrentDateView : View {
@State var newDate = Date()

let timer = Timer.publish(every: 1, on: .current, in: .common).autoconnect()

var body: some View {
Text("\(newDate)")
.onReceive(timer) {
self.newDate = Date()
}
}
}

SwiftUI - Timer to update text

You can try using SwiftUI formatting features vs using String

import SwiftUI
import Combine
struct WorldTimerView: View {
@StateObject var timers = TimerData()
//Use TimeZone directly
@State var timezones: [TimeZone] = [TimeZone.current, TimeZone(identifier: "America/Halifax")!]
var body: some View {
List {
ForEach(timezones, id: \.self) { timeZone in
Text(timers.date, formatter: formatter)
//Inject the TimeZone to the Text
.environment(\.timeZone, timeZone)

//You can also use style
Text(timers.date, style: .time).environment(\.timeZone, timeZone)
}
}

}
var formatter: DateFormatter{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "h:mm:ss a"
return dateFormatter
}
}

Update Label Text with Timer Values

I see a few issues:

  • The finance object goes out of scope when fireTimer() returns. It will be deallocated then. The timer will be setting a label text on a no longer existing view controller.
  • Instantiating a UIViewController with FinanceVC() doesn't display it on screen. After instantiating you need to explicitly show. You can do this for example by calling present(_:animated:completion:) from a parent view controller.
  • The timer updates dayLabelText which does not update dayLabel.text

Might be good to follow a basic YT tutorial on how to display a view controller.

Good luck, you'll get it soon enough!

SwiftUI update Textlabel from Background Timer

Change your body to.

var body: some View {
VStack {
Text("\(timeLeft)")

Button(action: {
self.start.toggle()
self.notifyTime = Date().addingTimeInterval(TimeInterval(10)) // add countdown time in sec
self.timeLeft = timeDifference(endTime: self.notifyTime)
self.sendNotification()
//Timer code - Start your timer
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
timeLeft -= 1

if timeLeft == 0 {
timer.invalidate()
//Add your new trigger event
}
}
}) { Text("Start Countdown (10s)")}

}.onAppear(perform: {
UNUserNotificationCenter.current().requestAuthorization(options: [.badge,.sound,.alert]) { (_, _) in
}
})
}

SwiftUI: Updating Model with a timer and reflecting it in UI

I wouldn't rely on a mutating member of the struct to project the changes to the @Published wrapper. I'd use something that explicitly gets/sets the model.

This, for example, works:


struct ContentView: View {

@ObservedObject var viewModel = ViewModel()

var body: some View {
Text(viewModel.number)
}
}

class ViewModel: ObservableObject, HeartbeatModifier {

@Published private var model = Model()
var emitter = HeartbeatEmitter()

init() {
emitter.delegate = self
}

func beat() {
model.number += 1
}

var number: String {
"\(model.number)"
}
}

protocol HeartbeatModifier {
func beat()
}

protocol Heartbeat {
var number : Int { get set }
}

struct Model: Heartbeat {
var number: Int = 0
}

class HeartbeatEmitter {

private var timer: Timer!
var delegate: HeartbeatModifier?

init() {
setupTimer()
}

func setupTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(notifyDelegate), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: .common)
}

@objc
func notifyDelegate() {
delegate?.beat()
}
}

SwiftUI Timer.publish causing whole screen to refresh

If you want to refresh only a part of body, then separate that part into dedicated subview, eg:

struct ApptCardView: View {

@ObservedObject var apptCardVM: ApptCardViewModel

var body: some View {
VStack {
CurrentDateView() // << here !!

Picker("Seizure Type", selection: $apptCardVM.typeIndex) {
ForEach(0..<apptCardVM.typeChoice.count) {
Text(self.apptCardVM.typeChoice[$0])
}
}.pickerStyle(SegmentedPickerStyle())

}

}
}

struct CurrentDateView: View {
@State private var currentDate = Date()
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
Text("\(currentDate)")
.onReceive(timer) { input in
self.currentDate = input // << refresh only own body !!
}
}
}


Related Topics



Leave a reply



Submit