简体   繁体   English

在 SwiftUI 的后台任务中以开放形式显示消息

[英]Show messages in open form from background task in SwiftUI

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.但无论我如何尝试,在任务完成并且控件返回到 from 控件之前都没有更新。

So what I did in the Content-View, I defined it like:所以我在 Content-View 中做了什么,我将它定义为:

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:为了在 SwiftUI 中定义它,我定义了该结构,因为不允许使用类:

// 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 如下所示:

// 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.这是在模拟后台进程中更新txt的代码示例。

struct ContentViewsdsds: 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"
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM