For MacOS I use the following code many times to create forms. I really like to create a modifier or extension to make it more simplified.
HStack{
VStack (alignment: .leading, spacing: 5) {
Text("Account Number").font(.headline)
TextField("", text: $selectedBankAccount.accountNumber, prompt: Text("AccountNumber"))
}
}
.frame(width: 450 )
I would love to see something like:
struct FormStackModifier: ViewModifier {
var width : CGFloat
func body(content: Content) -> some View {
HStack {
VStack(alignment: .leading, spacing: 5) {
content
}
}
.frame(width: width)
}
}
// and use it like
ModifiedContent(
content: VStack { Text("Account Name").font(.headline)
TextField("", text: $selectedBankAccount.accountName, prompt: Text("AccountName"))},
modifier: FormStackModifier(width: 450)
)
But I need stil the extra VStack in content.
Is there a to solve this and a way to make this neat?
Group
is a view that does nothing but groups views together, allowing you to use multiple views as a single view. Unlike VStack
, it doesn't enforce a particular layout on the views or do anything like that.
You can replace the VStack
with Group
.
ModifiedContent(
content:
Group {
Text("Account Name").font(.headline)
TextField("", text: $selectedBankAccount.accountName, prompt: Text("AccountName"))
},
modifier: FormStackModifier(width: 450)
)
Using ModifiedContent
like this is rather inconvenient. I recommend adding an extension on View
that applies the FormStackModifier
.
extension View {
func formStack(width: CGFloat) -> some View {
modifier(FormStackModifier(width: width))
}
}
// usage:
Group {
Text("Account Name").font(.headline)
TextField("", text: $selectedBankAccount.accountName, prompt: Text("AccountName"))
}
.formStack(width: 450)
Alternatively, instead of a ViewModifier
, you can make your own View
called FormStack
:
struct FormStack<Content: View>: View {
let width : CGFloat
let content: Content
init(width: CGFloat, @ViewBuilder content: () -> Content) {
self.width = width
self.content = content()
}
var body: some View {
HStack {
VStack(alignment: .leading, spacing: 5) {
content
}
}
.frame(width: width)
}
}
// usage:
FormStack(width: 450) {
Text("Account Name").font(.headline)
TextField("", text: $selectedBankAccount.accountName, prompt: Text("AccountName"))
}