Aneel
Aneel

Reputation: 1433

Make a SwiftUI TextField big enough to fit a string

I'd like to use SwiftUI to make a TextField that's wide enough to fit a certain number of digits. It should take into account the current font, so I can't use a fixed value.

I know that I can get the current font with: (https://stackoverflow.com/a/62156787/1115020)

@Environment(\.font) var font

And convert that to a UIFont with a table: (https://stackoverflow.com/a/64491669/1115020)

extension UIFont {
    class func with(font: Font) -> UIFont {
        let uiFont: UIFont
        
        switch font {
        case .largeTitle:
            uiFont = UIFont.preferredFont(forTextStyle: .largeTitle)
        case .title:
            uiFont = UIFont.preferredFont(forTextStyle: .title1)
        case .title2:
...

And get the width of a string using that by doing this: (https://stackoverflow.com/a/58782429/1115020)

extension String {
   func widthOfString(usingFont font: UIFont) -> CGFloat {
        let fontAttributes = [NSAttributedString.Key.font: font]
        let size = self.size(withAttributes: fontAttributes)
        return size.width
    }
}

And finally setting the frame appropriately:

.frame(width: "9999".widthOfString(usingFont: UIFont.with(font: font ?? .body)))

But the resulting box is a little too small because of the padding, and the whole process is a bit convoluted.

Is there a simpler way?

Upvotes: 3

Views: 295

Answers (1)

pawello2222
pawello2222

Reputation: 54426

You can create a Text with longest possible string and hide it. Then put the actual TextField in an overlay:

Text("9999999999")
    .opacity(0)
    .overlay(TextField("", text: $text))

Upvotes: 3

Related Questions