SwiftUI TextField selects all text when it gains focus — how to move caret to the end like in AppKit?

I’m running into an issue with TextField focus behavior in SwiftUI.

By default, when I set focus to a TextField programmatically (using @FocusState), SwiftUI behaves like AppKit — the entire contents of the text field are selected. This is causing problems for my use case, because I want the caret placed at the end of the text without selecting everything.

How I solved this in AppKit

In AppKit, I worked around this by subclassing NSTextField and overriding becomeFirstResponder to adjust the editor’s selection:

override func becomeFirstResponder() -> Bool {
    let responderStatus = super.becomeFirstResponder()
    
    // Ensure caret is placed at the end, no text selected
    if let editor = self.currentEditor() {
        let selectedRange = editor.selectedRange
        editor.selectedRange = NSRange(location: selectedRange.length, length: 0)
    }
    
    return responderStatus
}

This successfully prevented AppKit from auto-selecting the entire string when focus changed.

The problem in SwiftUI

Now I see the same auto-select behavior in SwiftUI when I toggle focus with @FocusState. But unlike AppKit, SwiftUI doesn’t expose the underlying NSTextView or UITextField APIs, so I can’t directly adjust the selection or caret position.

Questions:

Is there a way in SwiftUI to control the caret/selection behavior when a TextField becomes focused? Is there a built-in modifier or @FocusState trick I’m missing?

Has anyone found a reliable SwiftUI-idiomatic approach to ensure the caret is placed at the end of the text instead of selecting all text?

update:

adding my swiftUI code below:

struct TextFieldUI: View {
    @ObservedObject var pModel:TextFieldModel
    @FocusState private var pIsFocusedState: Bool
    
    var body: some View {
        VStack(spacing: 20) {
            TextField(pModel.placeholder, text: $pModel.text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
                .focused($pIsFocusedState)
                .onChange(of: pModel.isFocused) { old, newValue in
                    pIsFocusedState = newValue
                }
                .onChange(of: pIsFocusedState) { old, newValue in
                    pModel.isFocused = newValue
                }
                .onAppear {
                    pIsFocusedState = pModel.isFocused
                }

            Toggle("Secure Mode", isOn: $pModel.isSecure)
                .padding()
        }
        .padding()
    }
}
SwiftUI TextField selects all text when it gains focus — how to move caret to the end like in AppKit?
 
 
Q