Обновить текст в SwiftUI, пока процесс еще работает - PullRequest
1 голос
/ 19 апреля 2020

Мне нравится обновлять текст на экране, чтобы информировать пользователя о прогрессе. Я использую текст в SwiftUI. Всякий раз, когда я изменяю это сообщение, оно должно обновляться, даже если процесс все еще выполняется. Например:

@State private var message = "-"

    var body: some View {

        VStack {
            Button("Run") {
                print("Tapped!")
                for i in 0 ... 100 {
                    self.message = "\(i)"
                    for _ in 1...1000 {
                        print(".")  // some time consuming stuff
                    }
                }
            }

            Text(message)
                .frame(width: 100)
                .padding()
        }
        .padding(40)
    }

Когда я меняю сообщение, оно должно обновлять экран. К сожалению, он обновляет только текст, когда циклы завершены, поэтому он показывает 100. Он должен показывать 1, 2, ... 100.

Нужны ли мне специальные сложные очереди, как в разработке classi c используя «DispatchQueue.main.asyn c» и т. д. c или в SwiftUI есть более простой способ?

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Я предпочитаю DispatchQueue, поэтому некоторые альтернативные

Button("Run") {
    print("Tapped!")
    DispatchQueue.global(qos: .background).async {
        for i in 0 ... 100 {
            DispatchQueue.main.asych {
                self.message = "\(i)"
            }
            for _ in 1...1000 {
                print(".")  // some time consuming stuff
            }
        }
    }
}
1 голос
/ 19 апреля 2020

swift слишком быстр для простой распечатки 1000 операторов ...

, кстати ... трудоемкие вещи должны выполняться всегда НЕ в основном потоке, а работа с пользовательским интерфейсом всегда должна выполняться в основной поток;)

попробуйте

struct ContentView: View {
    @State private var message = "-"

    var body: some View {

        VStack {
            Button("Run") {
                print("Tapped!")
                OperationQueue().addOperation {
                    for i in 0 ... 100 {

                        OperationQueue.main.addOperation {
                            self.message = "\(i)"
                        }
                        sleep(1)
                    }

                }
            }

            Text(message)
                .frame(width: 100)
                .padding()
        }
        .padding(40)
    }
}
...