The model increments through a range of dates converted to Double and scaled, ranging from 0 to 1.0
I wish to show a determinate progress bar.
As I understand it, the ProgressView() must be declared in the ContentView and its progress var must be declared as a @State var
The ContentView declares the model vars as @EnvironmentObjects
If I declare: @State private var = model.progressValue I get the error:"Cannot use instance member 'model' within property initializer; property initializers run before 'self' is available"
btw the model class declares: @Published var progressValue : Double
The model func (to increment through dates) is launched by a button in the ContentView.
idk how to get the incremented progressValue from the model to the ContentView State var.
Found a solution! Search: "quick-start/swiftui/how-to-show-progress-on-a-task-using-progress" Use a Timer to allow ProgressView to update from EnvironmentObject vars. Then you must config your app-file with the proper .environmentObject()
app-file:
import SwiftUI
@main
struct test_progressView_EnvObjApp: App {
var body: some Scene {
WindowGroup {
ContentView().environmentObject(Model.init(progressValue: 0.0))
}
}
}
Model-file:
import Foundation
import SwiftUI
class Model: ObservableObject {
@Published var t_step : Double
@Published var progressValue : Double
init (progressValue: Double){
self.t_step = 0.0
self.progressValue = 0.0
}
func stepThroughTime() {
var when = DispatchTime.now()
progressValue = 0.0
let _ = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { timer in
DispatchQueue.global().asyncAfter(deadline: when ) { [self] in
DispatchQueue.main.async { [self] in
if progressValue >= 0.9 { progressValue = 0.0 }
else { progressValue = progressValue + 0.1 }
}
when = when + .seconds(2)
}
}
}
}
ContentView-file:
import SwiftUI
struct ContentView: View {
@EnvironmentObject var model: Model
@State var progressValue = 0.0
let timer = Timer.publish(every: 2.0, on: .main, in: .common).autoconnect() // seconds
var body: some View {
VStack {
Button(
action: {
model.stepThroughTime()
}
)
{ Text("Search") }.environmentObject(model)
ProgressView(value: progressValue ).onReceive(timer) { _ in
progressValue = model.progressValue
}.padding()
.environmentObject(model)
}.environmentObject(model)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Thanks to Claude31 for the DispatchQueue-ProgressValue portion. See my post on the subject.