概览
为了更好的在 SwiftUI 中使用修改器,我们一般会将修改器包装到 View 的扩展方法中,比如下面的 KeyboardAdaptive 修改器:
struct KeyboardAdaptive: ViewModifier {
@State private var keyboardHeight: CGFloat = 0
func body(content: Content) -> some View {
content
.padding(.bottom, keyboardHeight)
.onReceive(Publishers.keyboardHeight) { self.keyboardHeight = $0 }
}
}
如果在视图上直接使用它,我们得这样写:
struct ContentView: View {
@State private var text = ""
var body: some View {
VStack {
Spacer()
TextField("Enter something", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.padding()
.modifier(KeyboardAdaptive())
}
}
这略显冗长,若我们将它的调用放到 View 扩展中去,则可以大大简化代码,这在修改器包含若干默认参数时尤其有用:
extension View {
func keyboardAdaptive() -> some View {
ModifiedContent(content: self, modifier: KeyboardAdaptive())
}
}
VStack {
Spacer()
TextField("Enter something", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
.padding()
.keyboardAdaptive()
可以注意到,除了在视图扩展中使用 ModifiedContent 应用修改器,我们还可以直接使用 .modifier 来调用修改器:
extension View {
func keyboardAdaptive() -> some View {
self.modifier(KeyboardAdaptive())
}
}
那么,这两种方式生成的视图有什么区别呢?
且看分解!😎
探究
要想查看以上两者的区别,我们可以写一个简单的例子来测试一下:
struct TestModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding(100)
}
}
extension View {
func test1() -> some View {
ModifiedContent(content: self, modifier: TestModifier())
}
func test2() -> some View {
self.modifier(TestModifier())
}
}
在 Playground 中我们可以用 dump 方法查看以下三者的实际类型:
dump(Text("1").test1())
dump(Text("2").test2())
dump(Text("3").modifier(TestModifier()))
输出结果如下:
▿ SwiftUI.ModifiedContent<SwiftUI.Text, __lldb_expr_45.TestModifier>
▿ content: SwiftUI.Text
▿ storage: SwiftUI.Text.Storage.anyTextStorage
▿ anyTextStorage: <LocalizedTextStorage: 0x00006000020c5b80>: "1" #0
- super: SwiftUI.AnyTextStorage
▿ key: SwiftUI.LocalizedStringKey
- key: "1"
- hasFormatting: false
- arguments: 0 elements
- table: nil
- bundle: nil
- modifiers: 0 elements
- modifier: __lldb_expr_45.TestModifier
▿ SwiftUI.ModifiedContent<SwiftUI.Text, __lldb_expr_45.TestModifier>
▿ content: SwiftUI.Text
▿ storage: SwiftUI.Text.Storage.anyTextStorage
▿ anyTextStorage: <LocalizedTextStorage: 0x00006000020c5400>: "2" #0
- super: SwiftUI.AnyTextStorage
▿ key: SwiftUI.LocalizedStringKey
- key: "2"
- hasFormatting: false
- arguments: 0 elements
- table: nil
- bundle: nil
- modifiers: 0 elements
- modifier: __lldb_expr_45.TestModifier
▿ SwiftUI.ModifiedContent<SwiftUI.Text, __lldb_expr_45.TestModifier>
▿ content: SwiftUI.Text
▿ storage: SwiftUI.Text.Storage.anyTextStorage
▿ anyTextStorage: <LocalizedTextStorage: 0x00006000020ceb20>: "3" #0
- super: SwiftUI.AnyTextStorage
▿ key: SwiftUI.LocalizedStringKey
- key: "3"
- hasFormatting: false
- arguments: 0 elements
- table: nil
- bundle: nil
- modifiers: 0 elements
- modifier: __lldb_expr_45.TestModifier
可以看到,以上三者完全一致!
至此,我们解决了开头的那个疑问。
总结
在 SwiftUI 的学习中,除了按部就班的学习书本上的内容以外,我们还要时常对某些现象提出质疑并学会如何验证结果。
感谢观赏,再会!😉
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)