Capturing Text From Camera Using SwiftUI |

Learn how to capture text from the iPhone camera into your SwiftUI app so your users can enter data more quickly and easily.

This is a companion discussion topic for the original entry at

Thank you for this tutorial @audrey! I found it very helpful and informative.

I had a question surrounding behavior I noticed in the final version of the source materials.

Calling UIAction.captureTextFromCamera seems to open the camera in a bottom sheet properly for the first launch, but subsequent launches open in a semi-broken full screen state. (video below)

Screen recording of the bug

Opening a keyboard seems to reset the behavior.
Do you have any guidance on how to go about fixing this behavior so that all calls to UIAction.captureTextFromCamera behave the same?

hi Philip, glad you liked it!

Your video won’t play for some reason, but a similar thing happens on my phone, although I don’t think the full-screen view is broken…

UIAction.captureTextFromCamera is brand new for iOS 15, so it’s not surprising it still has a bug or two. Hopefully, this year’s WWDC will improve it. In the meantime, I would remove the button next to the text field and just rely on the text field focus bringing up the keyboard, with the camera button in its toolbar.

Thanks for the response @audrey! I think you are right — I filed a task in Feedback Assistant (FB9838054).

Here’s an image that shows the bugs I found while in the full screen mode. I’d be curious to hear if they are just showing up for me, or if you notice them as well. I wonder if there’s a way to contain the live text view so that it respects the top safe zone.

One workaround for the close button obfuscation might be to hide the status bar when the camera opens, though i’m not sure how to detect when it is hidden again.

hi Philip, yes I see the same problem … Apple’s own apps don’t have this problem … secret sauce :woman_shrugging:

Although ScanButton does not automatically limit the text selection from the TextField textContentType, you can still manually implement this because the coordinator implements UIKeyInput which inherits from UITextInputTraits.

To do this, I added a property to ScanButton:

var textContentType: UITextContentType? = nil

In the coordinator define the property:

var textContentType: UITextContentType!

and change the initializer to

    init(_ parent: ScanButton, textContentType: UITextContentType? = nil) {
      self.parent = parent
      self.textContentType = textContentType

Finally, update makeCoordinator():

  func makeCoordinator() -> Coordinator {
    Coordinator(self, textContentType: textContentType)

Back in AddPersonView, the default behavior will be to not specify a TextContentType, which is the prior behavior. but now you can specify the textContentType on the Scanbutton in the toolbar for the birthday field:

ScanButton(text: $birthday, title: .constant(title), textContentType: .dateTime)

This provides the behavior as before, but manually specified.

1 Like