SwiftUI: modifier是创建一个新视图还是返回一个修改后的视图?



我正在阅读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。

基本上没有任何对象的实例(除了描述)表示视图,颜色或角半径可以存在之前,它的初始化基于描述和当前状态,因此没有实例持有属性(如字体),可以分配或更改在最终视图被初始化。

相关内容

  • 没有找到相关文章

最新更新