#view #swiftui #reload
#Вид #swiftui #перезагрузите
Вопрос:
У меня есть некоторый текст внутри представления, и я хочу, чтобы этот текст изменил его положение по таймеру. У меня есть следующее:
struct AlphabetView: View {
@State var timer: Publishers.Autoconnect<Timer.TimerPublisher> = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
@State var refreshMe: Bool = false // this is a hack to refresh the view
var relativePositionX: CGFloat {
get { return CGFloat(Float.random(in: 0...1)) }
}
var relativePositionY: CGFloat {
get { return CGFloat(Float.random(in: 0...1)) }
}
var body: some View {
GeometryReader { geometry in
Text("Hello World!")
.position(x: geometry.size.width * self.relativePositionX, y: geometry.size.height * self.relativePositionY)
.onReceive(timer) { _ in
// a hack to refresh the view
self.refreshMe = !self.refreshMe
}
}
}
}
Я полагаю, что представление должно перезагружаться каждый раз, когда изменяется self.refreshMe, потому что это @State . Но я вижу, что положение текста изменяется только при перезагрузке родительского представления рассматриваемого представления. Что я делаю не так (кроме взлома)? Есть ли лучший способ сделать это?
Комментарии:
1. Ваш хак не работает, потому что ваш view фактически не используется
refreshMe
. Достаточно добавить что-то вроде.foregroundColor(self.refreshMe ? .black : .black)
, чтобы SwiftUI запустил обновление.2. Кстати,
CGFloat
тоже есть.random(in:)
, такvar relativePositionX: CGFloat { .random(in: 0...1) }
что этого достаточно.
Ответ №1:
Вместо взлома просто обновите позицию напрямую.
Вот исправленный вариант. Протестировано с Xcode 12 / iOS 14.
struct AlphabetView: View {
let timer: Publishers.Autoconnect<Timer.TimerPublisher> = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
@State var point: CGPoint = .zero
var relativePositionX: CGFloat {
get { return CGFloat(Float.random(in: 0...1)) }
}
var relativePositionY: CGFloat {
get { return CGFloat(Float.random(in: 0...1)) }
}
var body: some View {
GeometryReader { geometry in
Text("Hello World!")
.position(self.point)
.onReceive(timer) { _ in
self.point = CGPoint(x: geometry.size.width * self.relativePositionX, y: geometry.size.height * self.relativePositionY)
}
}
}
}
Комментарии:
1. Это полностью решает проблему, большое вам спасибо.