【问题标题】:Reload SwiftUI view from within it从其中重新加载 SwiftUI 视图
【发布时间】:2020-10-11 18:21:41
【问题描述】:

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

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 不起作用,因为您的视图实际上并未使用 refreshMe。添加 .foregroundColor(self.refreshMe ? .black : .black) 之类的内容足以让 SwiftUI 触发更新。
  • 顺便说一句,CGFloat 也有.random(in:),所以var relativePositionX: CGFloat { .random(in: 0...1) } 就足够了。

标签: view swiftui reload


【解决方案1】:

直接更新位置而不是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)
                }
        }
    }
}

【讨论】:

  • 这样就彻底解决问题了,非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 2018-12-24
  • 2020-12-29
  • 2018-02-21
相关资源
最近更新 更多