Изменение текстового вида - отображение прогресса длительной операции
Я пытаюсь показать ход длительной операции в текстовом представлении. Используя StateObject/Published var, я надеялся увидеть изменение текста при изменении опубликованного var, однако я вижу только последний текст, появляющийся в текстовом поле. Как я могу динамически изменять/обновлять текстовое поле?
@StateObject var tt = TestText()
var body: some View {
Text(tt.text)
.padding()
.onAppear(perform: { tt.ChangeText() })
}
class TestText: ObservableObject {
@Published var text = "text 0"
func ChangeText() -> Void {
sleep(3) // some time-consuming stuff here
text = "text 1"
sleep(3) // id
text = "text 2"
sleep(3) // id
text = "text 3"
sleep(3) // id
text = "text 4"
sleep(3) // id
text = "text 5"
}
}
2 ответа
твойsleep(3)
неправильно, он не имитирует длительную задачу,
он останавливает все (включая обновление пользовательского интерфейса) на 3 секунды. То, что вы хотите, это что-то вроде этого, чтобы имитировать длительную задачу:
struct ContentView: View {
@StateObject var tt = TestText()
var body: some View {
Text(tt.text)
.padding()
.onAppear(perform: { tt.ChangeText() })
}
}
class TestText: ObservableObject {
@Published var text = "text 0"
func ChangeText() -> Void {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.text = "text 1"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
self.text = "text 2"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 6) {
self.text = "text 3"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 8) {
self.text = "text 4"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
self.text = "text 5"
}
}
}
Спасибо, что указали мне правильное направление. Сон был просто заполнителем для длительной операции, но различные операции выполняются последовательно. С небольшой модификацией вашего кода я достиг своей намеченной цели. Теперь биты кода запускаются один за другим, показывая обновленный текст после каждого шага.
import Foundation
class TestText: ObservableObject {
@Published var text = "text 0"
func ChangeText() -> Void {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.DoSomething()
self.text = "text 1"
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.DoSomething()
self.text = "text 2"
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.DoSomething()
self.text = "text 3"
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.DoSomething()
self.text = "text 4"
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.DoSomething()
self.text = "text 5"
}
}
}
}
}
}
func DoSomething() -> Void {
sleep(3) // these are in fact various bits of codes, which have to run in sequence one after the other, DoSomething is just a placeholder for the moment
}
}