问题
最近在写 SwiftUI 的时候遇到了一件怪事。
Swift
struct AView: View {
@State private var content: String
var body: some View {
Text(content)
}
}
#Preview {
AView(content: "Test")
}
上面的代码没有问题,参数可以传递给 AView
被 @state
标记的参数 content
。
紧接着我们把 conten 变成 optional,结果还是一样符合预期。
Swift
struct AView: View {
@State private var content: String?
var body: some View {
Text(content ? "")
}
}
#Preview {
AView(content: "Test")
}
不过当我们给 View 添加初始化方法后,奇怪的事情就开始出现了。外面的参数无法传递给 conten
了,最终 Aview
展示了空字符串。 打断点看了一下,参数确实传递进去了,但走到 body
方法内部时,content
是空的(类型是State<Optional<String>>
, _value = nil)。
Swift
struct AView: View {
@State private var content: String?
var body: some View {
Text(content ? "")
}
init(content: String) {
self.content = content
}
}
#Preview {
AView(content: "Test")
}
网上查了一下,发现如果给 View
加 init
方法,需要用特殊的方式给 State
属性赋值。
Swift
init(content: String) {
_content = State(initialValue: content)
}
我理解被 @State
包装的属性类型已经变了(State<Type>
)。我们在 View
的上下文中可以直接修改它,但是在初始化方法中不行。
不过当我们把 content
从 optional
改成 非 optional
时,情况又变了。不需要使用特殊的方式,值一样可以通过 init
方法传递给 content
。。。
Swift
struct AView: View {
@State private var content: String
var body: some View {
Text(content)
}
init(content: String) {
self.content = content
}
}
#Preview {
AView(content: "Test")
}
结论
一般我们不会主动去写 View
的 init
方法,不过当参数比较多且不是必要参数时,我们可能会重写 init
方法给参数默认值,以简化初始化方法。如果在之后的开发者遇到了参数无法传递问题,可以尝试使用 State
的构造方法来赋值。