This raises an interesting point. You don't want to make large views by having standard controls with lots of modifiers, but you want some kind of reuse, either by using a function to return the view or a custom view.
When I face these problems in SwiftUI I look to see what I am extracting. In your case it looks like the controls are standard, but they have different styling applied to them. The clue is in the function names that all have render.
In this case, rather than using a function or a custom View, I would write a custom modifier that applies a set of common styles to a control. A couple of examples from your code:
First, create 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)
}
}
These are quite simple to write. You just apply the modifiers you want to the content parameter.
And to make them easier to use, you can write extension to View
extension View {
func inputTextFieldStyle() -> some View {
modifier(InputTextFieldModifier())
}
func buttonTextStyle() -> some View {
modifier(ButtonTextModifier())
}
}
And this makes the call site look something like this:
var body: some View {
VStack {
...
TextField(...)
.inputTextFieldStyle()
...
Button(action: {print("Button clicked")}){
Text("LOGIN")
.buttonTextStyle()
}.padding()
}
}
If you want to be able to configure the modifier, that is easy as well. Say you want to specify the background colour of your common text fields, you can re-write the modifier to take this as a parameter:
struct InputTextFieldModifier: ViewModifier {
let backgroundColor: Color
func body(content: Content) -> some View {
content
.padding()
.background(backgroundColor)
.cornerRadius(5.0)
.padding(.bottom, 20)
}
}
And update your convenience function to take this as a parameter:
extension View {
func inputTextFieldStyle(backgroundColor: Color) -> some View {
modifier(InputTextFieldModifier(backgroundColor: backgroundColor))
}
}
And at the call site:
TextField("Username", text: $username)
.inputTextFieldStyle(backgroundColor: Color.gray)
And custom modifiers are reusable.