SwiftUI Question: how to know when a user is editing a particular SecureField...?

I've asked this question already on Apple Developer Forums (link here) and StackOverflow (link here) to no avail. I'm hoping that someone here might know an answer to this.

What's the best way to know when a user is editing a particular SecureField in SwiftUI? Our designers want the text field's border to be thicker when it's being edited. We also want to scroll that field into view if it's tabbed into from off-screen.

At first we tried using an .onTapGesture modifier attached to the SecureField, however this does not work because:

  • onTapGesture fails to detect when the user tabs between fields using a hardware keyboard
  • onTapGesture creates false positives when the user taps in the padding around the field (in this case the field does not start editing even though they tapped inside the border around it... very annoying especially since there's no way to customize the size of the hit-box for a particular SecureField).

Why isn't there something equivalent to the UITextFieldDelegate methods in the form of a view modifier? Something like a .onBeginEditing, or .willBeginEditing? I don't see that there's any modifiers like this available for SecureField.

The only solution I've been able to come up with, is to use GeometryReader to record the CGRect associated with each SwiftUI SecureField, then compare it against the contents of UIKeyboard.willChangeFrameNotification, UITextField.didBeginEditingNotification, and UITextField.didEndEditingNotification (since those notifications indicate the CGRects associated with the text fields being edited).

However that solution seems pretty far from ideal since it depends on UIKit details that SwiftUI is supposed to abstract away, and it requires us to perform expensive numerical comparisons between CGRects any time the user starts editing a different field.

How can we do stuff like this in SwiftUI with SecureField? Are we really supposed to resort to comparing CGRects or wrapping multiple platform-specific implementations anytime we want to customize basic aspects of UI?

Note: SwiftUI TextField lets you initialize it with a closure, onEditingChanged, which gives exactly the functionality I'm asking about. But Apple chose not to have this same closure on SecureField... why?

Also why is TextFieldStyle protocol totally empty {}?

Thanks.

Pretty sure all of the XStyle things in SwiftUI are private. I tried to make a new ListStyle and quickly ran into shrouded mysteries.

Not all. Just the ones where, I guess, Apple hasn't yet seen fit to actually flesh out the API. Maybe next year... just seems like certain really critical, core things are still missing.

You can observe edit with a binding:

    @State private var password = ""

    var body: some View {
        // you can observe edit with this
        let binding = Binding(get: { password }, set: { password = $0; print("new password: \($0)") })
        VStack {
            SecureField("Password", text: binding)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding(20)
                .multilineTextAlignment(.center)

            Text("Result: \(password)")
        }
    }

Also willSet()/didSet() on @​State work now.

Terms of Service

Privacy Policy

Cookie Policy