swiftiphoneuikittext-recognition

Looking for Swift UITextField Shortcut to "Scan Text" Option


On the iPhone, when you double-tap a text field, you get the options to Paste or AutoFill. When you choose AutoFill, one of the options is Scan Text, which opens a forward-facing camera preview on the bottom third of the screen ready to capture text with nothing more than an Insert and a Cancel button. I need to do this in several places inside an app built on Storyboard.

This is for capturing VINs through the windshield of cars primarily, and it works well. But believe it or not, the test users were a bit dumbfounded by the screenshots of the five-tap process. So I am hoping for an UITextField extension, or maybe a class I can initiate when editing begins on a text field, that will immediately initiate Scan Text functionality upon tapping into the VIN field.

I've googled quite a bit over the past few weeks, and I know how to open the camera easy enough, I don't see how I can get rid of the red shutter option and replace it with the Insert button, though.... not to mention showing the capture brackets around recognized text in the preview. If I had to, I know how to recognize text in any picture they take and extract it easy enough, and I'm sure I can figure out how to place the camera preview in the lower third of the current view.... but I am hoping to avoid all that. It seems like it should be easier than that since Scan Text is a core function of the iPhone.

Am I missing something obvious hopefully? I'd appreciate and ideas or further reading. Thanks!


Solution

  • UIResponder provides the captureTextFromCamera(_:) method. You just need to call this on your text field.

    If you want this to appear automatically when the text field becomes first responder then setup your view controller as a UITextFieldDelegate and add the following:

    func textFieldDidBeginEditing(_ textField: UITextField) {
        // Make sure the user's device can scan text from a camera
        if textField.canPerformAction(#selector(UIResponder.captureTextFromCamera(_:)), withSender: self) {
            textField.captureTextFromCamera(self)
        }
    }
    

    Of course there are any number of options for where you could call captureTextFromCamera on the text field.

    If you wanted to use this from a button handler, you can do something like this:

    @IBAction func buttonHandler(_ sender: UIButton) {
        // Make sure the text field is the first responder so the text scanning results appear as expected
        if !textField.isFirstResponder {
            textField.becomeFirstResponder()
        }
    
        // Make sure the user's device can scan text from a camera
        if textField.canPerformAction(#selector(UIResponder.captureTextFromCamera(_:)), withSender: self) {
            textField.captureTextFromCamera(self)
        }
    }
    

    where the action buttonHandler is connected to the "Touch Up Inside" event of your UIButton outlet. And textField should be replaced with your UITextField outlet or property.