We made a custom keyboard and uploaded to the App Store, the design and the keyboard works fine. However we get a lot 1-star reviews due to slowness of the buttons. The question is. Is there a way to speed UIButtons
up?
UIControl's touchUpInside
works once the user release their finger off the button, in some cases people write so fast and touchUpInside
isn't the "Fast" way do do it
TouchDown
will fire before TouchUpInside
because touch down is the action of your finger touching down on the phone.
Please advice on this, What and Which way do you generally prefer for a production keyboard
This is my current method of handling a tap: which's too slow!
func buttonAction(_ sender:UIButton!) {
print("Button tapped")
self.textDocumentProxy.insert("B")
}
The speed of TouchDown vs. TouchUpInside isn't really the issue. The problem comes when users are typing with both thumbs and the key strokes are interpreted in the wrong order.
Apple’s default keyboard registers a key on touch up. But, on the iPhone, if a second key is pressed while the first is down, then the first key is registered then and doesn’t wait for its touch up. This keeps the input in the touch down order (for two thumb typing), but still reflects the touch up behavior.
To implement this, you need to observe both TouchDown and TouchUpInside events.
Here is one way you could do it. Create a property called pendingButton
to track the last button pressed down, and process that button either when it is let up or another button is pressed down.
You'll need to connect buttonDown
to TouchDown events and buttonUp
to TouchUpInside events.
// last button pressed down
var pendingButton: String?
// connect button TouchDown events here
@IBAction func buttonDown(_ sender: UIButton) {
// If we already have a pending button, process it before storing
// the next one
if let pending = self.pendingButton {
self.textDocumentProxy.insert(pending)
}
self.pendingButton = sender.currentTitle
}
// connect button TouchUpInside events here
@IBAction func buttonUp(_ sender: UIButton) {
// If the button being let up is the latest pending button,
// then process it, otherwise ignore it
if sender.currentTitle == self.pendingButton {
self.textDocumentProxy.insert(self.currentTitle!)
self.pendingButton = nil
}
}
Note: You might also want to consider carefully other events such as TouchUpOutside. That should probably be connected to buttonUp
as well depending on the desired behavior of your keyboard.
If instead, dragging outside of a button cancels the button, then you should implement a function to observe TouchDragExit and then cancel the pending button if that is the pending button.
// connect button TouchDragExit events here
@IBAction func dragExit(_ sender: UIButton) {
if sender.currentTitle == self.pendingButton {
self.pendingButton = nil
}
}