WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

Adding a clear button to a TextField

Forums > 100 Days of Swift

In UIKit you can set textField.clearButtonMode = .whileEditing to make the text field automatically show a standard clear button inside that clears the text once the user types something. I was looking for a way to do that in SwiftUI, but the answers I found suggest either: 1) setting it globally for all buttons using UIAppearance, or 2) creating a custom button that just happens to look similar and is overlaid on top of the text field - so basically I have a choice between a hacky solution and a very hacky solution…

What's the least hacky way to do this (I assume there's no built-in modifier that sets this like .keyboardType for the keyboard type)?

1      

Ok, but… the code you've shown above does what you said is a band-aid, it creates a custom button that looks like it's the built-in text field clear button that iOS provides, but isn't one, right? I want to tell SwiftUI "I want this TextField to show exactly the thing that UITextField shows when configured with clearButtonMode", not something that looks and works like that button, but something that is that button. So that when iOS 16 is released that happens to show this clear button in UITextFields in a different way, my text field will also look that way.

1      

There is no native SwiftUI way to show that button at the present time. You have to either a) roll your own TextField replacement using a UIViewRepresentable to wrap a UITextField, b) use UIAppearance to force it, or c) create a button using SwiftUI, something like this:

struct TextFieldClearButton: ViewModifier {
    @Binding var fieldText: String

    func body(content: Content) -> some View {
        content
            .overlay {
                if !fieldText.isEmpty {
                    HStack {
                        Spacer()
                        Button {
                            fieldText = ""
                        } label: {
                            Image(systemName: "multiply.circle.fill")
                        }
                        .foregroundColor(.secondary)
                        .padding(.trailing, 4)
                    }
                }
            }
    }
}

extension View {
    func showClearButton(_ text: Binding<String>) -> some View {
        self.modifier(TextFieldClearButton(fieldText: text))
    }
}

struct TextFieldButton: View {

    @State private var text = ""
    @FocusState private var isTextFieldFocused: Bool

    var body: some View {
        VStack {
            TextField("", text: $text)
                .textFieldStyle(.roundedBorder)
                .focused($isTextFieldFocused)
                .showClearButton($text)
        }
        .padding()
        .background(Color.purple)
    }
}

I know it seems hacky, but that the way you do things in SwiftUI until Apple sees fit to give us a native way of doing it.

2      

You can also try the new .searchable(text: ) https://www.hackingwithswift.com/quick-start/swiftui/how-to-add-a-search-bar-to-filter-your-data

With this you get the clear button and the magnifying glass icon for free!

   

Hacking with Swift is sponsored by Emerge

SPONSORED Optimize your app’s startup time, binary size, and overall performance using Emerge’s advanced app optimization and monitoring tools. Reliably measure app size, speed up your app's startup time with Emerge's Launch Booster, and much more. Emerge is actively used by many of the top mobile development teams in the world.

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.