我是学习 Swift 和 SwiftUI 的新手。我有一个包含 VStack 的视图结构。在 VStack 中,我调用了四个返回视图的函数。
var body: some View {
VStack {
self.renderLogo()
self.renderUserNameTextField()
self.renderPasswordSecureField()
self.renderLoginButton()
}
}
func renderLoginButton() -> some View {
return Button(action: {print("Button clicked")}){
Text("LOGIN").font(.headline).foregroundColor(.white).padding().frame(width: 220, height: 60).background(Color(red: 0, green: 70/255, blue: 128/255)).cornerRadius(15.0)
}.padding()
}[...]
我刚刚读到,将视图提取到这样的结构中更为常见:
struct UsernameTextField : View {
@Binding var username: String
var body: some View {
return TextField("Username", text: $username)
.padding()
.background(lightGreyColor)
.cornerRadius(5.0)
.padding(.bottom, 20)
}
}
这是为什么?使用结构体代替普通函数有什么优势?
答案 0 :(得分:2)
如果该视图与主视图至少有一个 @Binding
,我会在不同的结构中分离视图。否则,我会坚持功能。但是...
如果您想在单独的结构或函数中执行此操作取决于您,但要考虑到如果您想重用视图,如果将其声明为单独的视图会更容易实体。
这样做的另一个目的是避免在 SwiftUI 中拥有庞大的视图,将职责分离成更小的视图,使代码更易于阅读。
答案 1 :(得分:2)
这提出了一个有趣的观点。您不想通过使用带有大量修饰符的标准控件来制作大型视图,但您想要某种形式的重用,无论是通过使用函数返回视图还是自定义视图。
当我在 SwiftUI 中遇到这些问题时,我会查看我正在提取的内容。在您的情况下,控件看起来是标准的,但它们应用了不同的样式。线索在于函数名中都有 render
。
在这种情况下,我不会使用函数或自定义视图,而是编写一个自定义修饰符,将一组通用样式应用于控件。代码中的几个示例:
首先,创建 ViewModifiers
struct InputTextFieldModifier: ViewModifier {
func body(content: Content) -> some View {
content
.padding()
.background(Color.gray)
.cornerRadius(5.0)
.padding(.bottom, 20)
}
}
struct ButtonTextModifier: ViewModifier {
func body(content: Content) -> some View {
content
.font(.headline)
.foregroundColor(.white)
.padding()
.frame(width: 220, height: 60)
.background(Color(red: 0, green: 70/255, blue: 128/255))
.cornerRadius(15.0)
}
}
这些写起来很简单。您只需将所需的修饰符应用于内容参数即可。
为了使它们更易于使用,您可以将扩展名写入 View
extension View {
func inputTextFieldStyle() -> some View {
modifier(InputTextFieldModifier())
}
func buttonTextStyle() -> some View {
modifier(ButtonTextModifier())
}
}
这使得呼叫站点看起来像这样:
var body: some View {
VStack {
...
TextField(...)
.inputTextFieldStyle()
...
Button(action: {print("Button clicked")}){
Text("LOGIN")
.buttonTextStyle()
}.padding()
}
}
如果您希望能够配置修改器,那也很容易。假设要指定常用文本字段的背景颜色,可以重新编写修饰符以将其作为参数:
struct InputTextFieldModifier: ViewModifier {
let backgroundColor: Color
func body(content: Content) -> some View {
content
.padding()
.background(backgroundColor)
.cornerRadius(5.0)
.padding(.bottom, 20)
}
}
并更新您的便利函数以将其作为参数:
extension View {
func inputTextFieldStyle(backgroundColor: Color) -> some View {
modifier(InputTextFieldModifier(backgroundColor: backgroundColor))
}
}
在呼叫站点:
TextField("Username", text: $username)
.inputTextFieldStyle(backgroundColor: Color.gray)
并且自定义修饰符是可重复使用的。
答案 2 :(得分:1)
更建议将您的 views
提取到 structs
,这样您以后可以在代码中重用您的视图,使您的代码更加干净和隔离。