Inspired by @BenzyNeez`s answer, i've made a small and simple View
that:
Hides this issue
Have frame that hugs TextField
Made in SwiftUI
, so we can continue to use modifiers like .focus()
struct StableHuggingTextfield: View {
var placeholder: String
@Binding var text: String
private let hPadding: CGFloat = 4
private let minWidth: CGFloat = 60
var body: some View {
Text(text)
.allowsHitTesting(false)
.lineLimit(1)
.truncationMode(.head)
//Padding to match Text frame to TextField's size
.padding(.horizontal, hPadding)
.padding(.vertical, 5)
.frame(minWidth: minWidth, alignment: .leading)
.background { //If overlay, then there is problem when selecting text
TextField(placeholder, text: $text)
.foregroundStyle(.clear)
.frame(minWidth: minWidth - hPadding*2)
}
}
}
Also, in this code i've added minWidth
, as it is required in my project, but it works just fine without it.
Comparison of native, stable and NSViewRepresentable
textfield's
However, this approach have some problems:
Truncation is not the same as in regular TextField
. In textfield it just clips text, but .truncationMode()
replaces part of the text with "...". This results in jumping when editing after max width has been reached. I believe it can be fixed with Text
clipping truncation.
If text is truncated, sometimes the cursor disappears for some reason.
In some layouts horizontal padding must be changed to some other value.
For my project, these issues are unlikely to occur, so i'm going to stick with this result.
I've also re-tested Auto-Growing NSTextField
from this post, that i've mentioned in the question, and it have the same issue, which is fixed with margin, so not ideal. Basically, we're required to do some hacking to have stable TextField
, which is sad.