0

On a view I have something like this:

TextFieldUsername()

this shows something like

enter image description here

So, this view shows an icon and the textfield username.

Below that, I have another one for the password.

Making that username field in focus is unnecessarily hard. The textfield is not small, but making the username field to focus is a matter of tapping on the exact position and perhaps you have to tap 2 or 3 times to make it happen.

I would like to make the whole TextFieldUsername() tappable or to increase the hit area of that textfield. I would like better to make the whole thing tappable and once tapped, make its textfield in focus.

This is TextFieldUsername

struct TextFieldUsername: View {
  
  @State var username:String
 

  var body: some View {
    
    HStack {
      Image(systemName: "person.crop.circle")
        .renderingMode(.template)
        .foregroundColor(.black)
        .opacity(0.3)
        .fixedSize()

      TextField(TextFieldUsernameStrings.username, text: $username)
        .textFieldStyle(PlainTextFieldStyle())
        .textContentType(.username)
        .autocapitalization(.none)
      
    }
  }
}

Is that possible in SwiftUI without using any external library like introspect?

Duck
  • 34,902
  • 47
  • 248
  • 470

1 Answers1

1

Using a custom TextField like the one from Matteo Pacini

you can do something like this:

struct CustomTextField1: UIViewRepresentable {
    class Coordinator: NSObject, UITextFieldDelegate {
        @Binding var text: String
        var didBecomeFirstResponder = false
        init(text: Binding<String>) {
            _text = text
        }
        func textFieldDidChangeSelection(_ textField: UITextField) {
            text = textField.text ?? ""
        }
    }
    @Binding var text: String
    var isFirstResponder: Bool = false
    func makeUIView(context: UIViewRepresentableContext<CustomTextField1>) -> UITextField {
        let textField = UITextField(frame: .zero)
        textField.delegate = context.coordinator
        return textField
    }
    func makeCoordinator() -> CustomTextField1.Coordinator {
        return Coordinator(text: $text)
    }
    func updateUIView(_ uiView: UITextField, context:     UIViewRepresentableContext<CustomTextField1>) {
        uiView.text = text
        if isFirstResponder && !context.coordinator.didBecomeFirstResponder  {
            uiView.becomeFirstResponder()
            context.coordinator.didBecomeFirstResponder = true
        }
    }
}

struct ContentView : View {
    @State var text: String = ""
    @State var isEditing = false
    var body: some View {
        CustomTextField1(text: $text, isFirstResponder: isEditing)
            .frame(width: 300, height: 50)
            .background(Color.red)
            .onTapGesture {
                isEditing.toggle()
            }
    }
}

It's a bit complex, but should get the work done. As for a pure SwiftUI answer, it's currently unavailable.

Timmy
  • 4,098
  • 2
  • 14
  • 34