6

I have a TextField in SwiftUI. When I apply padding to it as

TextField(text, text: $value)
    .padding()

the padding is outside of the tap area of the TextField, i.e. tapping on the padding does not bring the text field into focus.

I would like to be able to focus the TextField even if the user taps on the padding.

Vivek Roy
  • 193
  • 1
  • 7
  • 2
    Check if [this](https://stackoverflow.com/questions/56795712/swiftui-textfield-touchable-area/) answer your question – ScorpiCon Feb 13 '21 at 11:41
  • That's awfully complicated for something so basic. Having to include libraries just to add padding to my TextField properly. Anyway. Thanks @ScorpiCon – Vivek Roy Feb 13 '21 at 12:12
  • Does this answer your question? [SwiftUI TextField touchable Area](https://stackoverflow.com/questions/56795712/swiftui-textfield-touchable-area) – Nelu Dec 03 '21 at 14:27

7 Answers7

10

You can try this. At least worked for me. Hope that helps someone:

            TextField("", text: $textfieldValueBinding)
                .frame(height: 48)
                .padding(EdgeInsets(top: 0, leading: 6, bottom: 0, trailing: 6))
                .cornerRadius(5)
                .overlay(
                    RoundedRectangle(cornerRadius: 5)
                        .stroke(lineWidth: 1.0)
                )
Hector Rubial
  • 101
  • 1
  • 3
1

you can check this. for now i only did with top and bottom padding. you can do the same with the leading and trailing(or with horizontal and vertical). as asked in the question this would do this "I would like to be able to focus the TextField even if the user taps on the padding."

struct ContentView: View {
@State var name = ""
@State var isTextFieldFocused = false
var body: some View {
        ZStack {
            HStack{
                Text(name)
                    .font(.system(size: 50 , weight: .black))
                    .foregroundColor(isTextFieldFocused ? Color.clear : Color.black)
                Spacer()
            }
            TextField(name, text: $name , onEditingChanged: { editingChanged in
                isTextFieldFocused = editingChanged
            }) 
            .font(.system(size: isTextFieldFocused ? 50 :  100 , weight: .black))
            .foregroundColor(isTextFieldFocused ? Color.black  : Color.clear)
            .frame(width: 300, height: isTextFieldFocused ? 50 :  100 , alignment: .center)
                        .padding(.leading, isTextFieldFocused ? 25 : 0  )
                        .padding(.trailing, isTextFieldFocused ? 25 : 0 )
            
            .padding(.top,isTextFieldFocused ? 25 : 0 )
            .padding(.bottom,isTextFieldFocused ? 25 : 0 )
            
        }.frame(width: 300)
        .background(Color.red.opacity(0.2))
}
}
Ahmad
  • 195
  • 1
  • 12
  • This does not answer the question. It adds padding if the textfield does change. But the question is *how to focus the TextField when the user taps the added padding*. – Ali May 05 '21 at 08:13
  • This is the answer from https://stackoverflow.com/questions/56795712/swiftui-textfield-touchable-area. My issue with it is I have to tap twice for the textfield to focus if text has previously been entered. – Nelu Dec 03 '21 at 14:26
0

Yes, but you have to create your own TextFieldStyle. Here's an example:

struct CustomTextField: View {
    
    public struct CustomTextFieldStyle : TextFieldStyle {
        public func _body(configuration: TextField<Self._Label>) -> some View {
            configuration
                .font(.largeTitle) // set the inner Text Field Font
                .padding(10) // Set the inner Text Field Padding
                //Give it some style
                .background(
                    RoundedRectangle(cornerRadius: 5)
                        .strokeBorder(Color.primary.opacity(0.5), lineWidth: 3)) 
        }
    }
    @State private var password = ""
    @State private var username = ""
    
    var body: some View {
        VStack {
            TextField("Test", text: $username)
                .textFieldStyle(CustomTextFieldStyle()) // call the CustomTextField
            SecureField("Password", text: $password)
                .textFieldStyle(CustomTextFieldStyle())
        }.padding()
    }
}
0

The Only way that worked for me has been to write a custom TextFieldStyle and then, add .padding(.horizontal) within the style.

struct RegisterLoginTextFieldStyle: TextFieldStyle {
    var width: CGFloat
    var height: CGFloat
    var fontSize: CGFloat

    func _body(configuration: TextField<Self._Label>) -> some View {
        configuration
            .frame(width: width, height: height)
            .padding(5)
            .padding(.horizontal)
            .border(Color.black, width: 2)
            .background(Color.textFieldBackground)
            .font(.system(size: fontSize))
            .foregroundColor(.black)
    }
}

...
var body: some View {
    TextField(
        label,
        text: $input
    )
    .padding(.top, 5)
    .textFieldStyle(
        RegisterLoginTextFieldStyle(
            width: width,
            height: height,
            fontSize: placeholderSize
        )
    )
}

textfield with horizontal inner padding

Alex G. Luque
  • 13
  • 3
  • 4
  • The issue is not how to add padding, but how to make it so the textfield would focus when you tap the padding. That does not seem to work with this code. – Nelu Dec 03 '21 at 14:23
0

Add HStack around your TextField and then you can play with HStack: Example:

example textField

         VStack {

                ...
                
                
                HStack {
                        TextField("Social security number", text: $socialNumber)
                            .disableAutocorrection(true)
                }
                .padding()
                .padding(.leading, 30.0)
                .padding(.trailing, 30.0)
                .background(RoundedRectangle(cornerRadius: 12).fill(Theme.color.textFieldBackgroundColor))
                .frame(maxWidth: 315)
                
                ...
            }
            .padding(.top, 0)
            .frame(maxWidth: 350)
Tiago Mendes
  • 3,577
  • 1
  • 31
  • 32
  • This makes the TextField look bigger than it actually is and will thus confuse the user. Tapping on the padded area of the HStack will not activate the TextField and so the user might think I'm tapping on it but nothing is happening leading to a bad user experience. Adding a touch listener on the HStack to activate the TextField might fix this but I was looking for something simpler than that (if possible) – Vivek Roy Nov 04 '21 at 15:38
  • @VivekRoy when I finish the project that I am working on with swiftUI, I am going to go back to UIKit + Snapkit way better control in all elements. – Tiago Mendes Nov 04 '21 at 16:41
0
TextField(
    "TextFiled",
    text: $teamNames,
    prompt: Text("Text Field")
        .foregroundColor(.gray)
)
    .padding(5)
    .frame(width: 250, height: 50, alignment: .center)
    .background(
        RoundedRectangle(cornerRadius: 25, style: .continuous)
            .foregroundColor(.white)
            .padding(.horizontal, -30)
    )
Farshid
  • 11
  • 2
-2

I don't know if you can give padding inside of a TextField, but you can pad it from outside environment and give it a background of a shape with the same color of your TextField background.

Try this;

        TextField("Username", text: $value)
            .background(Color.yellow)
            .padding(50)
            .background(Capsule().fill(Color.white))