4

I'm trying to implement such component

enter image description here

TextField (5 000) and Text (PLN) together should be centered horizontally. On entering new digit's, Text (PLN) should be dismissed. I think I have to combine this two views in to one container and center in, something like

HStack {
   TextField()
   Text("PLN")
}
.frame(alignment: .center)

But TextField is taking all possible width.

How could I handle it, or probably another solution.

Konstantin.Efimenko
  • 1,242
  • 1
  • 14
  • 38
  • What do you mean with "On entering new digit's, Text (PLN) should be dismissed." Should it be dismissed, when the TextField has more than 4 characters in it, or be dismissed, while you are typing in the TextField, ...? – Kuhlemann May 15 '20 at 12:45
  • Imagine that This is a one view 5000PLN And it could have different length, but should be always centered. – Konstantin.Efimenko May 15 '20 at 12:53

2 Answers2

9

Here is possible approach with dynamically sized TextField.

Note: helper rectReader is taken from this my post.

Tested with Xcode 11.4 / iOS 13.4 (black border is only for demo)

demo

struct DemoCenterTextField: View {
    @State private var value = ""
    @State private var frame = CGRect.zero

    var body: some View {
        return HStack(alignment: .bottom) {
            ZStack {
                Text(self.value).foregroundColor(Color.clear)
                    .fixedSize()
                    .background(rectReader($frame))

                TextField("#.#", text: $value)
                    .multilineTextAlignment(.trailing)
                    .frame(minWidth: 80, idealWidth: frame.width)
                    .fixedSize(horizontal: true, vertical: false)
                    .border(Color.black)      // << for demo only

            }.font(Font.system(size: 40).bold())

            Text("PLN")
        }
    }
}
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • @Asperi But .frame(minWidth: 80, idealWidth: frame.width) cause of constraints error "Contradictory frame constraints specified." Do you know how to avoid it? – Konstantin.Efimenko May 18 '20 at 15:30
  • 1
    @Konstantin.Efimenko, that is just a demo, with min limitation, but if want to continue with it, something like `.frame(minWidth: 80, idealWidth: max(frame.width, 80))` can be used (where minimum can be put into constant to avoid magic numbers). – Asperi May 18 '20 at 15:44
1

You can make the framesize depending on your amount of characters in the TextField to achive what you want:

struct ContentView: View {
    @State private var textField = ""

    var body: some View {

        HStack {
            TextField("", text: $textField)
                .frame(width: CGFloat(textField.count+10)*5, height: nil)
                .textFieldStyle(RoundedBorderTextFieldStyle()) // Just to illustrate the field better.
                .multilineTextAlignment(.center)
            Text("PLN")
                .offset(x: -15, y:0)
        }
    }
}
Kuhlemann
  • 3,066
  • 3
  • 14
  • 41