I have some text inside a View and I want this text to change it's position on timer. I have the following:
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
}
}
}
}
I suppose that the View should be reloaded every time self.refreshMe changes, because it is @State. But what I see is that the text position changes only when the parent view of the view in question is reloaded. What am I doing wrong (except hacking around)? Is there a better way to do this?
refreshMe. Adding something like.foregroundColor(self.refreshMe ? .black : .black)is enough to get SwiftUI to trigger the update.CGFloatalso has.random(in:), sovar relativePositionX: CGFloat { .random(in: 0...1) }is sufficient.