从其中重新加载 SwiftUI 视图

Reload SwiftUI view from within it

我在视图中有一些文本,我希望此文本更改它在计时器上的位置。我有以下内容:

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。但我看到的是,只有当相关视图的父视图重新加载时,文本位置才会改变。我做错了什么(除了黑客攻击)?有更好的方法吗?

不用 hack 直接更新位置。

这是更正后的变体。测试 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)
                }
        }
    }
}