Reputation: 3654
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.
Upvotes: 0
Views: 2113
Reputation: 3654
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.
Upvotes: -2