I have a background task which needs to show values to the open dialog. I read a lot of stuff about this tasks and adapted the tutorials to my needs. But regardless of my attempts, there is no update until the task is finished and the control is back in the from control.
So what I did in the Content-View, I defined it like:
struct ContentView: View {
@StateObject var infoText = InfoTextObject()
with type defined like:
class InfoTextObject: ObservableObject {
@Published var text = ""
}
For defining this in SwiftUI, I defined that struct, because classes are not allowed:
// small view with text message area
public struct InfoView: View {
@ObservedObject var it: InfoTextObject
public var body: some View {
TextField("Infos ...", text: $it.text)
.frame(alignment: .topTrailing)
.textFieldStyle(RoundedBorderTextFieldStyle())
.fixedSize(horizontal: false, vertical: false)
.disabled(true)
}
}
The body definition for the form looks like this
var body: some View {
VStack(alignment: .leading)
{
...
InfoView(it: infoText)
}
And finally the function which is called to update the screen with a new message looks like this:
// function to display any text in the view
func DisplayMessage(infoTextObject: InfoTextObject, _ text: String = "", debugMode : Bool = false) {
DispatchQueue.main.async {
infoTextObject.text = text
}
}
To me this looks very complex for such a simple and usual task. But even than it doesn't update. :-(
Any hints?
It's hard to tell what is going on, since the code you are showing us is not the code you are using.
Here is an example of the code that updates txt
in a simulated background process.
struct ContentView: View {
@State var infoText = ""
var body: some View {
VStack {
InfoView(txt: $infoText)
}
}
}
struct InfoView: View {
@Binding var txt: String
var body: some View {
TextField("Infos ...", text: $txt)
.frame(alignment: .topTrailing)
.textFieldStyle(RoundedBorderTextFieldStyle())
.fixedSize(horizontal: false, vertical: false)
.disabled(true)
Button(action: { DisplayMessage(infoText: $txt, "new message to display") }){
Text("Click for background task")
}
}
}
// simulating reporting updates during a long background process
func DisplayMessage(infoText: Binding<String>, _ text: String = "", debugMode : Bool = false) {
infoText.wrappedValue = text
DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 2) {
DispatchQueue.main.async {
infoText.wrappedValue = "processing"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
infoText.wrappedValue = "getting there"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
infoText.wrappedValue = "close to finishing"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
infoText.wrappedValue = "all done"
}
}
}