I have a problem. I have a view with several TextEditors. Typing in any of them changes the height of all of them.
Do you have any idea what happens and how to fix it?
Example Code:
import SwiftUI
struct TestingView: View {
@State var optionA = ""
@State var optionB = ""
@State private var comment = ""
var body: some View {
NavigationStack {
Form {
VStack() {
CustomRow(title: "Option A", value: $optionA)
CustomRow(title: "Option B", value: $optionB)
}
.padding(.vertical, 20)
}
.navigationTitle("Testing View")
.padding(.zero)
}
}
}
struct CustomRow: View {
var title: String = ""
@Binding var value: String
var body: some View {
VStack(alignment: .leading) {
Text(title)
.font(.system(.headline, design: .rounded))
.foregroundColor(.gray)
.listRowSeparator(.hidden)
ZStack {
TextEditor(text: $value)
.padding(4)
.autocapitalization(.none)
.disableAutocorrection(true)
.textFieldStyle(.roundedBorder)
.font(.system(.body, design: .rounded))
.frame(minHeight: 50, maxHeight: 200)
}
.overlay(
RoundedRectangle(cornerRadius: 4)
.stroke(.gray, lineWidth: 1)
)
}
.padding(.bottom, 10)
}
}
struct TestingView_Previews: PreviewProvider {
static var previews: some View {
TestingView()
}
}
I think this is because VStack
s try to layout its views by distributing them equally along the vertical axis, whenever it can. Since you gave the text editors a flexible height between 50 and 200, they can be stretched so that both text editors are equally tall.
From trial and error, you can fix this by adding a vertical fixedSize
to the VStack
:
VStack() {
CustomRow(title: "Option A", value: $optionA)
CustomRow(title: "Option B", value: $optionB)
}
.padding(.vertical, 20)
.fixedSize(horizontal: false, vertical: true)
But I would just do this as two separate rows of the form, and hide the list separator. If you want the vertical padding, add them separately to each CustomRow
:
Form {
Group {
CustomRow(title: "Option A", value: $optionA)
.padding(.top, 20)
CustomRow(title: "Option B", value: $optionB)
.padding(.bottom, 20)
}
.listRowSeparator(.hidden)
}
.navigationTitle("Testing View")
.padding(.zero)