14

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
  • 280
  • 1
  • 2
  • 8
  • 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

6 Answers6

20

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
  • 225
  • 2
  • 3
3

For iOS 15 and above you can use this:

var body: some View {
    TextField("placeholder", text: $text).focusablePadding()
}



extension View {
    
    func focusablePadding(_ edges: Edge.Set = .all, _ size: CGFloat? = nil) -> some View {
        modifier(FocusablePadding(edges, size))
    }
    
}

private struct FocusablePadding : ViewModifier {
    
    private let edges: Edge.Set
    private let size: CGFloat?
    @FocusState private var focused: Bool
    
    init(_ edges: Edge.Set, _ size: CGFloat?) {
        self.edges = edges
        self.size = size
        self.focused = false
    }
    
    func body(content: Content) -> some View {
        content
            .focused($focused)
            .padding(edges, size)
            .contentShape(Rectangle())
            .onTapGesture { focused = true }
    }
    
}
sugar baron
  • 165
  • 8
0

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
  • 348
  • 3
  • 14
  • 1
    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()
    }
}
-2
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
  • 17
  • 2
-4

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))