miltenkot
miltenkot

Reputation: 311

Different behavior of FocusState on iOS 17

I have a problem adding a field to the application where the user enters formatted text and has the ability to delete it when focused.

Interestingly, the application behaves correctly on iOS 17, and pressing 'x button' while typing deletes the text. However, on lower iOS versions, nothing happens and text doesn't disappear.

enter image description here

enter image description here

First gif (iOS 15.5) second (iOS 17.2) and here is my code.

import SwiftUI

struct ContentView: View {
    @FocusState var isFocused: Bool
    
    @State var text = 0
    var body: some View {
        VStack {
            HStack {
                TextField("write text here...",
                          value: $text,
                          format: .number)
                .focused($isFocused)
                .keyboardType(.numberPad)
                
                if isFocused {
                    Button("",
                           systemImage: "xmark.circle.fill") {
                        text = 0
                    }
                }
            }
            .border(.black)
        }
        .padding()
    }
}

Does anyone know what's going on and how to make the application work on all iOS versions the way it does on 17?

Upvotes: 0

Views: 451

Answers (2)

miltenkot
miltenkot

Reputation: 311

.onAppear {
   UITextField.appearance().clearButtonMode = .whileEditing
 }

this one works but if we have more than one TextField on view all have this button :( I don't know to prevent this behaviour

Upvotes: 0

MatBuompy
MatBuompy

Reputation: 2093

I don't get what's going on on iOS older than 17... Actually, it seems that iOS 16 has its issues, and iOS older than 16 have those problems but just a but bigger. The isFocused property is always on true on any version of the OS. The only way I've managed to make it work was this, toggling it on and off in the Button's action, which is a workaround really:

VStack {
            HStack {
                TextField("write text here...",
                          value: $text,
                          format: .number)
                .focused($isFocused)
                .keyboardType(.numberPad)
                .overlay(alignment: .trailing) {
                    Button("", systemImage: "xmark.circle.fill") {
                        if #available(iOS 17, *) {
                            text = 0
                            return
                        }
                        isFocused.toggle()
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                            text = 0
                        }
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
                            isFocused.toggle()
                        }
                    }
                    .opacity(isFocused ? 1 : 0)
                    .disabled(!isFocused)
                }
            }
            .border(.black)
        }
        .padding()

I've also improved a bit the layout using an overlay to display the X button and opacity and disable modifier to avoid showing and interacting with it. That behavior may as well be a bug on older os releases. Let me know if that solution could work for you!

Upvotes: 1

Related Questions