@FocusState problem

Hi

I have an enum of the TextFields in an Update SwiftData view. When the view opens, the focus is correct, and the button in the .toolbar keyboard sets the focus to nil and dismisses the keyboard. It works just fine.

But, if I tap on a different TextField other than the original field that the focus was set in a .onAppear, the button on the keyboard dims out and no longer works.

This same code works as expected in another view, the only difference in the Update view is that the data in the fields comes from an @Bindable variable.

Any clue what is going on? Thanks so much! Blessings, --Mark

Hi @foundationSW ,

Can you post some code snippets showing how you're currently trying to do this as well as the version that does work? Thanks!

Hi,

Thanks for checking, sorry I missed it, I did not have Notifications on.

I tried to post a response with code, but the forum errored out that I need something in the body.

Will try separate posts. The forst one is the code that FocusState works.

struct ServiceFormView: View {
    
    @Environment(\.modelContext) private var context
    @Environment(\.dismiss) var dismiss
    @FocusState private var focus: Field?
    @AppStorage("date") var date = Date()
    
    @State private var service = ""
    @State private var prop = ""
    @State private var count = ""
    @State private var place = ""
    @State private var presider = ""
    @State private var preacher = ""
    @State private var server = ""
    @State private var memo = ""
    @State private var communions = ""
    @State private var sundayAdded = false
    
    @State private var includeInASA = false
    @State private var addEuch = false
    @State private var showError = false
    
    var serviceType = ["Select Service", "Sunday Eucharist", "Weekday Eucharist", "Private Eucharist", "Sunday Office", "Weekday Office", "Burial", "Wedding", "Other"]
    
    private enum Field: Int, CaseIterable {
        case prop, count, place, presider, preacher,server, memo, communion
    }
    
    var body: some View {
        NavigationStack {
            ZStack {
                Color(.purple)
                    .opacity(0.3)
                    .ignoresSafeArea()
                VStack {
                    
                    DismissView()
                        .padding(.top, 15)
                    Group {
                        Text("Enter Service Record")
                            .font(.title)
                        
                        DatePicker("", selection: $date)
                            .frame(width: 90, alignment: .center)
                            .padding(.bottom, 30)
                        
                            VStack(spacing: 12) {
                                Picker("Select Service", selection: $service) {
                                    ForEach(serviceType, id: \.self) { service in
                                        Text(service).tag(service)
                                    }
                                }
                                .buttonStyle(.borderedProminent)
                            }
                    }
                    
                    if service == Constants.serviceList.privateEucharist || service == Constants.serviceList.other{
                            Toggle("Include in ASA", isOn: $includeInASA)
                                .frame(width: 200)
                    }
                        
                    if service == Constants.serviceList.burial || service == Constants.serviceList.marriage {
                        Toggle("Include in ASA", isOn: $includeInASA)
                            .frame(width: 225)
                        Toggle("Celebrate Eucharist", isOn: $addEuch)
                            .frame(width: 225)
                        if addEuch {
                            Text("Communions: ")
                            TextField("Communions", text: $communions )
                                .textFieldStyle(.roundedBorder)
                                .focused($focus, equals: .communion)
                                .numbersOnly($communions)
                                .frame(width: 125)
                        }
                    }
                        
                    Text("Attendance: ")
                        .padding(.top, 20)
                    TextField("Count", text: $count)
                        .textFieldStyle(.roundedBorder)
                        .frame(width:125)
                        .numbersOnly($count)
                        .keyboardType(.numberPad)
                        .focused($focus, equals: .count)
                    
                    if service == Constants.serviceList.eucharist ||
                        service == Constants.serviceList.weekdayEucharist ||
                        service == Constants.serviceList.privateEucharist {
                        Text("Communions: ")
                        TextField("Communions", text: $communions )
                            .textFieldStyle(.roundedBorder)
                            .focused($focus, equals: .communion)
                            .numbersOnly($communions)
                            .keyboardType(.numberPad)
                            .frame(width: 125)
                    }
                    
                    
                    
                        HStack {
                            TextField("Proper", text: $prop)
                                .textFieldStyle(.roundedBorder)
                                .focused($focus, equals: .prop)}
                            .padding(.top, 30)
                        
                        TextField("Place of service", text: $place)
                            .textFieldStyle(.roundedBorder)
                            .focused($focus, equals: .place)
                        
                    HStack {
                            TextField("Presider", text: $presider)
                                .textFieldStyle(.roundedBorder)
                                .focused($focus, equals: .presider)
                        
                            TextField("Preacher", text: $preacher)
                                .textFieldStyle(.roundedBorder)
                                .focused($focus, equals: .preacher)
                        
                            TextField("Server", text: $server)
                                .textFieldStyle(.roundedBorder)
                                .focused($focus, equals: .server)
                        }
                        
                        TextField("Memo", text: $memo)
                            .textFieldStyle(.roundedBorder)
                            .focused($focus, equals: .memo)
                        
                        Button {
                            addService()
                            dismiss()
                        } label: {
                            Text("Add")
                        }
                        .buttonStyle(.borderedProminent)
                        .font(.title)
                        .disabled(service.isEmpty)
                        .disabled(count.isEmpty)
                        .padding(.top, 30)
                    Spacer()
                }
                .padding()
            }
            .navigationBarBackButtonHidden()
            .toolbar {
                ToolbarItemGroup(placement: .keyboard) {
                    Spacer()
                        Button {
                            focus = nil
                        } label: {
                            Image(systemName: "keyboard.chevron.compact.down")
                        }
                }
            }
            .onAppear {
                UITextField.appearance().clearButtonMode = .whileEditing
                focus = .prop
            }
        }
    }
  
}

This second one works. If I click on the TextField, it is Focused. But when tapping on another TextFiled, the icon to dismiss the keyboard dims and can not be selected. Hence the problem.

struct UpdateFormView: View {
    @Environment(\.dismiss) var dismiss
    @FocusState private var focus: Field?
    @Bindable var item: Register
    
    private enum Field: Int {
        case communion, sunCount, weekCount, proper, place, officiant, preacher, server, memo
    }
    
    var body: some View {
        NavigationStack {
            ZStack {
                Color(.purple)
                    .opacity(0.3)
                    .ignoresSafeArea()
                VStack {
                    DismissView()
                        .padding(.top, 15)
                    Group {
                        Text("Update Service Record")
                            .font(.title)
                        Text("\(item.service)")
                            .font(.title3)
                        
                        DatePicker("", selection: $item.date)
                            .frame(width: 90, alignment: .center)
                            .padding(.bottom, 30)
                      
                        VStack {
                            
            
                        //static fields
                        TextField("Proper", text: $item.proper)
                            .textFieldStyle(.roundedBorder)
                            .focused($focus, equals: .proper)
                   
                    TextField("Place of service", text: $item.place)
                        .textFieldStyle(.roundedBorder)
                        .focused($focus, equals: .place)
                    
                    HStack {
                        TextField("Presider", text: $item.officiant)
                            .textFieldStyle(.roundedBorder)
                            .focused($focus, equals: .officiant)
                        
                        TextField("Preacher", text: $item.preacher)
                            .textFieldStyle(.roundedBorder)
                            .focused($focus, equals: .preacher)
                        
                        TextField("Server", text: $item.server)
                            .textFieldStyle(.roundedBorder)
                            .focused($focus, equals: .server)
                    }
                    
                    TextField("Memo", text: $item.memo)
                        .textFieldStyle(.roundedBorder)
                        .focused($focus, equals: .memo)
                    
                    Button {
                        dismiss()
                    } label: {
                        Text("Update")
                    }
                    .buttonStyle(.borderedProminent)
                    .font(.title)
                    .padding()
                    
                    Spacer()
                }
                .padding()
            }
            .navigationBarBackButtonHidden()
            .toolbar {
                ToolbarItemGroup(placement: .keyboard) {
                    Spacer()
                    Button {
                     focus = nil
                    } label: {
                        Image(systemName: "keyboard.chevron.compact.down")
                    }
                }
            }
            .onAppear {
                UITextField.appearance().clearButtonMode = .whileEditing
                focus = .proper
            }
        }
    }
}

Thanks for looking. Blessings, --Mark

So I've tried both of your code snippets and they work the same for me. The only change was that I had to comment out .numbersOnly($communions) and use my own state variables in the second snippet instead of Register binding that you had. I actually did not end up using @Bindable at all due to creating my own variables. You originally said:

This same code works as expected in another view, the only difference in the Update view is that the data in the fields comes from an @Bindable variable.

But neither snippet that worked for me used @Bindable

What iOS version are you testing this on? Are you on-device or on simulator? I've tested this on both with iOS 18 and iOS 17.5 and still have no issues with either snippet.

Hi Thanks for getting back to me..

The first snippet create a new record, so does not use @Bindable, but the second snippet is updating the SwiftData record, hence uses @Bindable.

I am running iOS 17.5 and using a 15 Plus to test.

The probelm is the icon in the keyboard tool bar dims if I select a diffrent TextField and the user can not dismiss. I would attach an image but Iguess that is not allowed.

Thanks. Blessings, --Mark

.toolbar {
                ToolbarItemGroup(placement: .keyboard) {
                    Spacer()
                    Button {
                     focus = nil
                    } label: {
                        Image(systemName: "keyboard.chevron.compact.down")
                    }
                }
            }

Hey Mark, I understand the problem but can't seem to replicate it. I went back to your earlier posts in which you wrote that both code snippets work, so can you please clarify which does not work?

Will try separate posts. The forst one is the code that FocusState works.

and

This second one works. If I click on the TextField, it is Focused. But when tapping on another TextFiled, the icon to dismiss the keyboard dims and can not be selected.

Is this second one the one that doesn't work? It still did work for me, when I click on a TextField and then tap on another, the icon to dismiss the keyboard does not dim for me. I did have to make the changes that I detailed earlier:

So I've tried both of your code snippets and they work the same for me. The only change was that I had to comment out .numbersOnly($communions) and use my own state variables in the second snippet instead of Register binding that you had. I actually did not end up using @Bindable at all due to creating my own variables.

Can you let me know if you've tested this on iOS 18 on a physical device?

@FocusState problem
 
 
Q