swiftswiftuitextfield

How to create a custom TextField that expands vertically with its content?


I’m trying to build a custom text field that automatically resizes its height based on the content (so if I type multiple lines, the field grows vertically).

Here is my current code:

import SwiftUI

struct CustomTextField: View {
    
    let title: String
    let prompt: String
    
    @Binding var text: String
    
    var body: some View {
        
        VStack(alignment: .leading, spacing: 10) {
            Text(title)
                .font(.title3.bold())
            TextField(prompt, text: $text, axis: .vertical)
        }
        .padding()
        .overlay {
            RoundedRectangle(cornerRadius: 15)
                .stroke(Color.black, lineWidth: 2)
        }
    }
}

#Preview {
    CustomTextField(
        title: "Title",
        prompt: "Prompt",
        text: .constant("This is my content")
    )
    .padding()
}

The problem is that the TextField doesn’t expand vertically when I type more text (and I understand why, but have no clue how to reach my goal). I would like it to behave like a single-line text input that automatically grows into multiple lines (similar to iMessage or WhatsApp input).

How can I make this CustomTextField grow in height based on its content while still keeping the title and border?


Solution

  • The TextField does expand vertically when you pass a binding to a state variable, instead of a binding to a constant:

    struct ContentView: View {
        @State private var text = "This is my content"
        var body: some View {
            CustomTextField(
                title: "Title",
                prompt: "Prompt",
                text: $text // 👈 here
            )
            .padding()
        }
    }
    

    Animation