SwiftUI 强制子视图重绘
Posted
技术标签:
【中文标题】SwiftUI 强制子视图重绘【英文标题】:SwiftUI force child view to redraw 【发布时间】:2020-12-09 12:37:12 【问题描述】:我有一个带有子视图的模态视图,它本身有另一个子视图。当我旋转设备时,需要重绘第一个子视图以将新的 GeometricReader 数据传递给最后一个子视图。
我正在通过视图模型中的通知中心检测旋转
@objc func updateView(_ : Notification)
self.refresh.toggle()
self.objectWillChange.send()
视图模型有两个属性。
@Published var objectWillChange = ObservableObjectPublisher()
@Published var refresh: Bool
在视图中我有一个@observedObject vm,但是当 vm 更改时,视图不会重绘。对于一些需要重新对齐的线条图,第一个孩子需要重绘以将其大小发送给第二个孩子。
[编辑]
struct StackView: View
@ObservedObject var vm = ViewModel()
var body: some View
Color.white
VStack
Spacer()
VStack
Text("Hello StackView")
View2()
extension StackView
final class ViewModel: ObservableObject
init()
NotificationCenter.default.addObserver(self, selector: #selector(updateView(_:)), name: UIDevice.orientationDidChangeNotification, object: nil)
deinit
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
@objc func updateView(_ notification: Notification)
self.objectWillChange.send()
struct View2: View
var body: some View
Text("Hello view 2")
.overlay(GeometryReader geo in
Color.clear
.onAppear
print(geo.frame(in: .global))
)
【问题讨论】:
我根本看不出该通知使用的任何原因。目标是什么 - 布局会在旋转时自动更新? 如你所说,旋转得到照顾,但我需要让 view2 重绘。该视图上有连接到图像的线,当它们由于旋转而移动时,它们需要获取更新的值。 【参考方案1】:@Published var objectWillChange = ObservableObjectPublisher()
删除此行。 ObservableObject
具有 objectWillChange
属性的默认发布者实现,所以只需使用它,就像
@objc func updateView(_ : Notification)
self.objectWillChange.send()
如果您对var refresh: Bool
没有特殊含义,则也不需要。
【讨论】:
它仍然不打球。视图 A 不会重绘(我应该会看到 GeometryReader 打印一些值),这意味着视图 B 也不会。 (同样有 GeometryReaders 应该打印值) 你能提供一些最小的可重现代码吗?我认为原始问题中遗漏了一些东西。顺便说一句,GeometryReader 不需要强制更新,它会自动更改尺寸,因此如果您不进行任何硬编码,那么内部部件应该无需干预即可更新。这看起来像是其他代码中某处的原因。 View2 中有一些硬编码的形状从框架中获取值,因此我需要重新绘制它以更新这些值。以上是关于SwiftUI 强制子视图重绘的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:ObservableObject 在重绘时不会保持其状态