I have a very simple TextEditor
in a SwiftUI Form
to allow users to send feedback about the app.
I want to set a minHeight
and maxHeight
for the text field so that it's clear the user can enter multiple lines. However, I also want to prevent the editor from expanding indefinitely and making it hard to access other form fields or the submit button.
*Problem: The issue I'm facing is that after typing for a while (or reaching a certain input length), the UI starts behaving unexpectedly — it starts adding phantom whitespace (or padding) to the bottom of the field. This happens when testing in Preview, the Simulator, and on a real device.
Here’s the code for the TextEditor
:
TextEditor(text: $description)
.frame(minHeight: 200, maxHeight: 400)
.disabled(processState.isRunning)
.fixedSize(horizontal: false, vertical: true)
.onChange(of: description) { _, newValue in
if newValue.count > characterLimit {
description = String(newValue.prefix(characterLimit))
}
}
What I've tried:
.onChange
logic to rule it out, but the issue persists.Has anyone encountered a similar issue with TextEditor in SwiftUI or have suggestions on how to fix or troubleshoot this?
Turns out it is an issue with embedding the TextEditor
within a Form
. I've logged a feedback (FB15475261) as there is no documentation stating this should not be used with a form.
I've been able to replicate it here (with the help of @Andrew_STOP_RU_WAR_IN_UA):
import SwiftUI
/// Please type in the TextEditor component and keep adding new lines into the field.
/// As you see once you hit around the 40th new line, it begins adding white space
/// or padding to the bottom of the TextEditor.
#Preview("TextEditor within Form") {
NavigationStack {
Form {
TextEditorView()
}
}
}
/// Please type in the TextEditor component and keep adding new lines into the field.
/// As you see there is no phantom white spacing when you keep creating new lines.
#Preview("TextEditor not within Form") {
VStack {
TextEditorView()
}
.padding()
}
struct TextEditorView: View {
@State private var description: String = ""
private var characterLimit = 2000
var body: some View {
Section {
TextEditor(text: $description)
.frame(minHeight: 200, maxHeight: 400)
.fixedSize(horizontal: false, vertical: true)
.onChange(of: description) { _, newValue in
if newValue.count > characterLimit {
description = String(newValue.prefix(characterLimit))
}
}
} header: {
HStack {
Text("Description")
Spacer()
Text("\(description.count) / \(characterLimit)")
.font(.caption2)
}
}
}
}