0

I am working on a setup screen with a dollar value and a picker. I have the dollar value setup with a currencyFormatter, and a .keyboardType(.decimalPad), if the user touches outside of the field, the .resignFirstResponder doesn't happen, so I added it to my Picker. However, If the user touches the picker, the .currencyFormatter is not applied.

 private var currencyFormatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.isLenient = true
        formatter.numberStyle = .currency
        return formatter
    }()
    var body: some View {
        GeometryReader { geometry in
            VStack{
                VStack{
                    HStack{
                        Text("Burden Rate: ")
                            .padding(.trailing)
                        Spacer()
                        TextField("Enter Burden Rate",
                                  value: $meetingSetup.saveRateValue,
                                  formatter: currencyFormatter,
                                  onEditingChanged: {_ in
                                    logger.log("editing changed")
                                  },
                                  onCommit: {
                                    logger.log("updated")
                                  }
                        )
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .multilineTextAlignment(.trailing)
                        .padding(.leading)
                        .keyboardType(.decimalPad)
                    }
                    HStack{
                        Text("Select One: ")
                        Spacer()
                        Picker("Calculation", selection: $selectedRateCalc) {
                            ForEach( 0 ..< rateCalc.count) {
                                Text(self.rateCalc[$0]).tag($0)
                            }
                        }
                        .pickerStyle(SegmentedPickerStyle())
                        .onChange(of: selectedRateCalc, perform: { value in
                            switch selectedRateCalc {
                            case 0:
                                meetingSetup.hourlyEnabled = false
                                meetingSetup.salaryEnabled = true
                                print("Salary Selected")
                            case 1:
                                meetingSetup.hourlyEnabled = true
                                meetingSetup.salaryEnabled = false
                                print("Hourly Selected")
                            default:
                                print("ERROR")
                            }
                            self.hideKeyboard()
                        })
                    }
                }
            }
            Spacer()
        }
    }
}
#if canImport(UIKit)
extension View {
    func hideKeyboard() {     UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}
#endif

I've reduced some of the other screen to make this cleaner for review. How can I correctly clear the keyboard AND have it format the currency correctly.

Michael Rowe
  • 870
  • 2
  • 11
  • 27
  • Because it is default behavior of SwiftUI TextField with formatter. You need solution like in https://stackoverflow.com/a/59509242/12299030. – Asperi Aug 26 '20 at 13:12
  • Thanks @Asperi, looking at the example, it doesn't look like this supports all the features of a TextField. When I tried to use it I get "Extra arguments at positions #1, #3, #4, and #5 in call". Which means that it only supports the value and the formatter. I've not tried to do extend such a basic function before. Also, when I tried to use it just using the value, I end up with very strange keyboard behavior, i.e. after the first digit it wants to put the decimal place. I guess I will have to raise a bug report with Apple until this behavior is correctly processed by default. – Michael Rowe Aug 27 '20 at 00:54

0 Answers0