我正在阅读SwiftUI材料,它说视图修饰符例如:
struct ByeView: View {
var body: some View {
Text("Bye bye, world!")
.font(.headline)
}
}
创建一个.headline
字体的新视图并返回该视图。
所以我想知道它是否更像是:
func font(_ font: UIFont) -> Text {
Text(text, font: font)
}
而不是:
func font(_ font: UIFont) -> Text {
self.font = font
return self
}
我觉得事件修饰符,因为他们可能不需要修改视图,没有必要"创建一个带有修改过的方面的新视图",但不确定修饰符是否会调整视图。
谢谢!
首先,注意像
这样的实现func font(_ font: UIFont) -> Text {
self.font = font
return self
}
不能编译。font
需要是mutating
才能起作用,但它不是mutating
。也就是说,这将编译为:
self.someReferenceType.font = font
但这有另一个问题。这意味着font
现在有一个副作用:
var body: some View {
let x = Text("foo")
x.font(.headline)
return x // this should have non-headline font, but if the
// implementation above were used, it would have headline font
}
所以我认为实际实现很可能涉及调用初始化器,而不是return self
。这也符合文档中"新视图"的措辞。是"created".
对于返回some View
的修饰符,您可以使用type(of:)
检查它们返回的类型。您很可能会看到它们返回的类型与self
不同,这意味着它们肯定不是return self
!毕竟,这就是为什么在签名中使用不透明类型some View
的原因之一——隐藏Apple用于实现这些修饰符的内部类型。
// doesn't work in a playground for some reason
// make a .swift file, compile and run
let x = Text("foo").onAppear {}
print(type(of: x))
对我来说,这打印:ModifiedContent<Text, _AppearanceActionModifier>
,而不是Text
,所以显然这里创建了一个新视图。(另见ModifiedContent
)
TLDR
我们不能确定,因为实现细节是隐藏的。
我的观点
我可能是错的,但我认为这是可能的,无论是修改视图的实例或分配给属性,你已经描述了实际发生,但我们不能确定,因为实现是私有的。
由于SwiftUI是一个声明式框架,你可以描述你想要得到什么,操作系统会照顾它,甚至可以这样写:
SomeView()
.padding()
.background(Color.red)
.cornerRadius(8)
在内部,它可以变成解析器可以读取的任何表示形式,例如JSON。
基本上没有任何对象的实例(除了描述)表示视图,颜色或角半径可以存在之前,它的初始化基于描述和当前状态,因此没有实例持有属性(如字体),可以分配或更改在最终视图被初始化。