ios - 为什么@EnvironmentObject 强制重新初始化视图?
问题描述
在此示例中,当我在屏幕上拖动时,为什么会LabelViewRepresentable
在每次“updateUIView”调用之前重新初始化?如果我将计数器设为@State
属性而不是@EnvironmentObject
属性,它只会像我期望的那样初始化一次。
import SwiftUI
class Counter: ObservableObject {
@Published var count = 0
}
struct CounterView: View {
@EnvironmentObject var counter: Counter
var body: some View {
LabelViewRepresentable(count: $counter.count)
.gesture(DragGesture().onChanged({ _ in
self.counter.count += 1
}))
}
}
struct LabelViewRepresentable: UIViewRepresentable {
@Binding var count: Int
private var view: UILabel
init(count: Binding<Int>) {
print("init")
let label = UILabel()
label.text = "0"
self.view = label
self._count = count
}
func makeUIView(context: UIViewRepresentableContext<LabelViewRepresentable>) -> UILabel {
print("makeUIView")
return view
}
func updateUIView(_ uiView: UILabel, context: UIViewRepresentableContext<LabelViewRepresentable>) {
print("updateUIView")
view.text = "\(count)"
}
}
解决方案
当您查看有关 EnvironmentObject 的 Apple 文档时,您会发现:
一个动态视图属性,它使用由祖先视图提供的可绑定对象,以在可绑定对象更改时使当前视图无效。
这意味着每次 EnvironmentObject 更改依赖于它的所有视图都会重新初始化和重绘。
它与 State 的工作方式略有不同,在 Apple 文档中描述如下:
给定类型的持久值,视图通过它读取和监视该值。
当状态更改时,视图无法重新初始化,因为状态值将被丢弃。受状态影响的部分将被重绘。另一方面,将 State 值作为绑定传入的视图的任何子视图都将被重新初始化。
推荐阅读
- .net - TLS 1.2 和现有连接被远程主机强行关闭
- r - R 绘图,名称在 y 轴上,值在 x 轴上
- r - 动态多个图,我怎么能一次调用它们?
- swift - Appcelerator Titanium - 无法找到或使用自动链接库“swiftCore”
- reactjs - Material-ui 自动完成过滤列表
- python - 将数字列转换为日期以进行时间序列分析
- r - 使用 JSON Web 令牌将文件发布到外部 API
- sql - Postgres - 获取第 X 周的星期一
- python - Tkinter 按字母顺序对网格元素进行排序
- docker - Neo4j 中的 docker 卷权限