A SwiftUI text field defaults to a single line that scrolls horizontally when needed. Starting with iOS 16, you can have it expand to a vertically scrolling, multi-line text field. Here’s what you need to know.
Text Fields
According to the Apple HIG, you use a text field for user input when you want a small amount of information such as a name or email address. For large amounts of text you use a text view (or TextEditor
if you’re working with SwiftUI):
Form {
Section("Your details") {
TextField("email", text: $email)
.textInputAutocapitalization(.never)
.autocorrectionDisabled(true)
}
Section("Feedback") {
TextEditor(text: $text)
}
}
I’ve never liked the way text fields work when the content gets too big to fit in the available space. Using a SwiftUI TextField
as you type beyond the field width the input text scrolls horizontally:
In some situations, I would prefer if the text field could extend over several lines.
Multi-line Text Fields
In iOS 16, you can specify an axis for the direction the text will scroll in when it fills the space. To have the text field scroll vertically:
TextField("email", text: $email, axis: .vertical)
Now when the text fills the available horizontal space the text field grows to allow room for an extra line. When the text field fills the available vertical space it scrolls the text input vertically.
Line Limits
The lineLimit
modifier, allows you to control the number of lines the text field shows. For example, to show up to four lines before scrolling:
TextField("email", text: $email, axis: .vertical)
.lineLimit(4)
The text field starts showing a single line, but will expand up to four lines before scrolling. Adding the reservesSpace
parameter fixes the visible size of the text field to always show that number of lines. For example, to make the text field always show four lines:
TextField("email", text: $email, axis: .vertical)
.lineLimit(4, reservesSpace: true)
Finally, you can use a range to set the minimum and maximum number of lines. For example, to always show at least two lines and expand up to a maximum of four lines before scrolling:
TextField("email", text: $email, axis: .vertical)
.lineLimit(2...4)
This starts with two lines:
Then as the text input grows in length the space expands to a maximum of four lines before scrolling vertically: