SwiftUI .task 未调用

SwiftUI .task not invoking

提问人:George Morris 提问时间:11/16/2023 更新时间:11/17/2023 访问量:75

问:

出于某种原因,当视图打开时,不会自动调用我的函数。如果我使用 调用函数,那么它就可以工作了。 为什么在这里不起作用?.taskButton("click") { Task { ... } }.task

import SwiftUI

struct BookTextView: View {
    @StateObject var viewModel: BookTextViewModel = BookTextViewModel()

    var body: some View {
        Text("HELLO!")
        Group {
            switch viewModel.result {
            case .empty:
                EmptyView()
            case .loading:
                ProgressView()
            case .failure(let error):
                Text(error.localizedDescription)
                //            ErrorView(error: error, retryHandler: viewModel.load)
            case .success(let bookText):
                ScrollView {
                    VStack(spacing: 20) {
                        Text(bookText.text)
                    }
                    .padding()
                }
            }
        }.task {
            do {
                try await viewModel.load()
            } catch {
                
            }
        }
    }
}

我的模型

import SwiftUI

@MainActor class BookTextViewModel: ObservableObject {
    enum AsyncResult<Success> {
        case empty
        case loading
        case success(Success)
        case failure(Error)
    }
    
    @Published var bookText: BookText?
    @Published var result: AsyncResult<BookText> = .empty
    

    func load() async {
        print("loading?")
        ...

这就是我从另一个组件调用视图的方式

 detail: {
            BookTextView()

迅捷 SwiftUI

评论

2赞 Sweeper 11/16/2023
这与类似。 类似于 ,因为它们都在视图首次出现时运行某些内容。 从未真正“出现”,因此永远不会运行。taskonAppearEmptyViewtask
0赞 workingdog support Ukraine 11/16/2023
尝试使用VStack{ Text....}.task {...}

答:

1赞 malhal 11/16/2023 #1

.task当出现某些东西时运行,因为您没有出现它,请将其删除并将您的移入机箱中,它应该会修复它。EmptyView()Text("HELLO!").empty

.task当它重新出现时也会运行(例如返回),因此您可能需要检查模型是否尚未加载,因此请避免再次加载它。

改进代码的一些技巧:将文本放入结果枚举中,而不是单独的 var 中。删除对象并仅使用,因为某种程度上已经在幕后创建了一个对象来管理生命周期。在其他地方声明你的异步乐趣,让它返回一些东西或抛出一些东西,这样更容易测试。@State var result.task