0

I have an iOS app with several numeric textfield fields using .keyboardType( .decimalPad) - but there's no way of sort of saying "yep" I'm done with editing now - so I want some sort of done or accept on the keyboard

When I search for that - I find heaps of examples, but they are mostly to do with UITextfield, not textfield - and set something called InputAccessoryView - which textfield apparently doesn't support. When I search filter them out - I find all sorts of strange wrappers and things that do things like add toolbars in the parent component, not the text field itself - and I have lots of text fields on lots of pages, so really want to solve it at the textfield level.

What I want is to build an extension to textfield - such that I can add a done button to dismiss it - ie this code here, but something that actually compiles - because the last line doesn't work:

extension TextField {
    func addDoneButtonOnKeyboard() {
        let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        doneToolbar.barStyle = .default

        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: nil)

        let items = [flexSpace, done]
        doneToolbar.items = items
        doneToolbar.sizeToFit()

        self.inputAccessoryView = doneToolbar
    }
}

so I can just say in my swiftui code:

     TextField("blah", $blah).addDoneButtonOnKeyboard()

also - I have had suggestions pointing me to other questions that do things like wrap a UITextField in UIRepresentable - to sort of access UIKit in swift... but I really want to arrive at a solution which is an extension on "TextField", and apart from the suggestion of using a 3rd party library, "introspect" - all the other suggestions end up creating a new class.

Darren Oakey
  • 2,894
  • 3
  • 29
  • 55
  • Does this answer your question? [Is it possible to change "return" key to "done" on keyboard in 2020 with SwiftUI?](https://stackoverflow.com/questions/60008549/is-it-possible-to-change-return-key-to-done-on-keyboard-in-2020-with-swiftui) – Nicolapps May 23 '21 at 12:18
  • maybe - it does involve adding an external library though, "introspect" - I'd still like to know how to do it myself. – Darren Oakey May 24 '21 at 04:16
  • It looks like there is currently no way to do it directly with the SwiftUI APIs. If you don’t want to use Introspect, you can create your own SwiftUI text field view based on the UIKit text field, as shown in this answer: https://stackoverflow.com/a/60736029/4652564 – Nicolapps May 24 '21 at 21:34

1 Answers1

-2

for anyone interested - I couldn't find anyway around introspect (one day I'll look at what it's doing and pull out the key parts) - but it did give me a solution - so with this extension:

public extension TextField
{
    func addDoneButtonOnKeyboard() -> some View
    {
        let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        doneToolbar.barStyle = .default
        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
        let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: nil, action: nil)
        doneToolbar.items = [flexSpace, done]
        doneToolbar.sizeToFit()
        return self.introspectTextField
        {
            text_field in
            text_field.inputAccessoryView = doneToolbar
            done.target = text_field
            done.action = #selector( text_field.resignFirstResponder )
        }
    }
}

all you have to do is add .addDoneButtonOnKeyboard() to your textfield in the view.

Darren Oakey
  • 2,894
  • 3
  • 29
  • 55