从其中重新加载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更改时都应该重新加载View,因为它是@State。但是我看到的是,仅当有问题的视图的父视图重新加载时,文本位置才会更改。我在做什么错(除了乱搞)?有更好的方法吗?

解决方法

不是直接破解,而是直接更新位置。

此处已更正变体。在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)
                }
        }
    }
}