简体   繁体   中英

SwiftUI: Padding inside TextField

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 , ie 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.

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

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

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

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

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

示例文本字段

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM