Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Problem with TextFields and decimals iOS17

After upgrading to iOS 17 I am struggling to get decimals working in my app - here is a sample code: for clarity I provide a complete "working" sample (I am pulling data from a back-end server using json, etc - all of that is working ok, it's the UI issue - see below):

Model

import Foundation

struct TestFloat: Encodable {
    var testFloatNumber: Float = 0
}

Observable Class

import Foundation

class TestFloatViewModel: ObservableObject {
    @Published var testFloat = TestFloat()
}

View

struct TestFloatView: View {
    
    @ObservedObject var testFloatVM: TestFloatViewModel

    let formatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter
    }()
    
    var body: some View {
        VStack {
            HStack {
                Text("Enter Float Number")
                Spacer()
            }
            Spacer()
                .frame(height: 2.0)
            HStack {
                TextField("Enter Float Number", value: $testFloatVM.testFloat.testFloatNumber, formatter: formatter)
                    .keyboardType(.decimalPad)
                    .textFieldStyle(.roundedBorder)
            }
        }
    }
}

This is working on a device with iOS16; however when run on device with iOS17:

  • you can enter maximum four digits?
  • using backspace you can delete all numbers apart of the first one
  • you cannot enter the decimal (.) at all even though decimal keyboard is provided

Any help is greatly appreciated.

I should add that this is not working when the Textfield is in .sheet or .fullScreenCover

I should actually clarify - this is not working when textField is in .sheet on .fullScreenCover. The code looks like so:

Main View

import SwiftUI

struct TestFloatView: View {
    @ObservedObject var testFloatVM: TestFloatViewModel
    
    @State private var showAddLoad = false
    
    var body: some View {
        VStack {
            HStack {
                Button {
                    showAddLoad = true
                    
                } label: {
                    Text("Text")
                }
            }
        }
        .fullScreenCover(isPresented: $showAddLoad, content: {
            NavigationView {
                EnterFloatView(testFloatVM: testFloatVM)
                    .navigationBarItems(
                        
                        leading: Button(action: {
                            showAddLoad = false
                        }, label: {
                            Text("Cancel")
                                .foregroundColor(Color("AccentRed"))
                        }),
                        
                        trailing: Button(action: {
                            showAddLoad = false
                            
                        }, label: {
                            Text("Save")
                                .fontWeight(.bold)
                        })
                    )
                    .navigationBarTitleDisplayMode(.inline)
            }
        })
    }
}

Sheet View

import SwiftUI

struct EnterFloatView: View {
    @ObservedObject var testFloatVM: TestFloatViewModel

    let formatter: NumberFormatter = {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter
    }()
    
    var body: some View {
        VStack {
            HStack {
                Text("Enter Float Number")
                Spacer()
            }
            Spacer()
                .frame(height: 2.0)
            HStack {
                TextField("Enter Float Number", value: $testFloatVM.testFloat.testFloatNumber, formatter: formatter)
                    .keyboardType(.decimalPad)
                    .textFieldStyle(.roundedBorder)
            }
        }
    }
}

If text field is placed in main view like in my original post, then it works OK.

I have the exact same issue in my app. I found out that it works with a state variable inside the view. I didn't have any luck binding to a variable inside of an observed object. Hence, my workaround relays the value from a state variable to the observed object.

@State private var price: Decimal?

func priceTextField() -> some View {
    let textField = TextField(
        "Price",
        value: $price,
        format: .number
    )
    .keyboardType(.decimalPad)
    .focused($focusedField, equals: .price)
    .onAppear {
        price = model.tx.decimalPrice
    }

    if #available(iOS 17.0, *) {
        return textField.onChange(of: price, initial: false) {
            model.tx.decimalPrice = price
        }
    }

    return textField
}

I also have the same problem with iOS 17. I have a TextField bound to an ObservedObject. If you then enter a comma (in Germany), the system deletes it again. Sometimes you can't edit the value itself. Strangely enough, sometimes it works all of a sudden, but usually it doesn't work.

The only workaround that works for me is to remove the @Published property from a variable like so:

import Foundation

class TestFloatViewModel: ObservableObject {
    @Published var testFloat = TestFloat()
}

This is not ideal because the view is not updated if I need the view to update when this variable is updated (if I don' need this variable to control/impact view updates, then it is less of a problem).

I applied this workaround because I need users to enter the data in a correct format, but I really don't understand why the original code is not working with iOS 17...

Apologies, the code above should read:

import Foundation

class TestFloatViewModel: ObservableObject {
    var testFloat = TestFloat()
}

Looks like iOS 17.1 and 17.2 don't fix the issue either :-(

Did any of you submit a feedback ticket to Apple for this issue? I am also facing issues with TextFields with Decimals in iOS 17

Same issue here (only in Sheets and only on iPad, not iPhone), very bizarre

This is a bug even today, on iOS 18.0.

Problem with TextFields and decimals iOS17
 
 
Q