У меня есть текст в поле зрения, теперь я хочу обновлять этот текст, используя оповещение каждую секунду.
Вот код, который я сделал.
struct CountDownView : View {
var body: some View {
VStack{
Text("Update text with timer").lineLimit(nil).padding(20)
}.navigationBarTitle(Text("WWDC"), displayMode:.automatic)
}
}





мне удалось обновить текст с помощью предупреждения.
я объявил дату как State, поэтому всякий раз, когда дата изменяется с помощью текста предупреждения, также будет обновляться.
struct CurrentDateView : View {
@State var newDate = Date()
let timer = Timer.publish(every: 1, on: .current, in: .common).autoconnect()
var body: some View {
Text("\(newDate)")
.onReceive(timer) {
self.newDate = Date()
}
}
}
@matt, каков наилучший подход?
Мэтт предоставил ссылку -- Nice. For an alternative (related) approach, see my stackoverflow.com/a/56905649/341994. – matt
@matt Можете ли вы уточнить, почему этот подход «неправильный»?
это работает для меня, но мой код немного отличается. Этот код просто синтаксически неверен
Использование комбинирования:
struct CurrentDateView : View {
@State var now = Date()
let timer = Timer.publish(every: 1, on: .current, in: .common).autoconnect()
var body: some View {
Text("\(now)")
.onReceive(timer) {
self.now = Date()
}
}
}
Хороший. Для альтернативного (родственного) подхода см. мой stackoverflow.com/a/56905649/341994.
Вам нужно получить доступ к переменной «сейчас» (любым образом) внутри тела. Если вы измените Text("(now)") на Text("(Date())"), представление не будет обновляться.
Понятно. Просто определите издателя следующим образом: let timer = Timer.publish(every: 1, on: .current, in: .common).autoconnect().first
Как сделать так, чтобы таймер срабатывал только один раз?
Если вы пойдете по этому пути, вам нужно будет аннулировать таймер при переключении видов. В противном случае он будет продолжать стрелять с неожиданными результатами.
Я обнаружил, что «общий параметр« P »не может быть выведен», когда я добавил .onReceive в свой код.
@BonoLv просто определите закрытие явно, например .onReceive(timer) { _ in ... }
исходный образец находился по адресу:
https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-a-timer-with-swiftui
Я использую этот подход для периодического обновления одного из моих вызовов...
см. также по адресу:
https://developer.apple.com/documentation/combine/replacing-foundation-timers-with-timer-publishers
struct ContentView: View {
@State var msg = ""
var body: some View {
let timer = Timer.publish(every: 1, on: .current, in: .common).autoconnect()
Text(msg)
.onReceive(timer) { input in
msg = MyManager.shared.ifo ?? "not yet received"
}
}
}
Мне приходится звонить в сеть другими способами, а здесь я просто периодически звоню некоторым своим менеджерам.
Чтобы остановить таймер (как в ссылке от hackingSwift..), вы можете использовать:
self.timer.upstream.connect().cancel()
Это неправильно. Я видел описание этого подхода в блогах и т. д., но это неправильно.