0

When using UIImagePickerController() it's easy to add an overlay image.

I'd like to dynamically get the "actual camera preview image area", i.e. indicated in a yellow box here:

enter image description here

(For example you might need to add an image guide overlay, crosshairs or such.)

If you poke around in Apple's views you'll soon see that CAMPreviewView is the best bet to get that frame.

Hence, I just cheaply find it using code like this that searches for "CAMPreviewView" in view stack. pc is the UIImagePickerController

if let foundFrame = pc.view.first(ofType: "CAMPreviewView")?.frame {
    yourOverlay.frame = foundFrame
}
else {
    print("Had to use a reasonable fallback ...")
    yourOverlay.frame = .. 
}

the yourOverlay is the

pc.cameraOverlayView = yourOverlay

(The yellow border image is indeed yourOverlay for the photo example above.)

This is a bit cheap and an anything could happen to Apple's code in the future.

Is there a better more authorized and standard way to add an "image overlay" on the image itself of UIImagePickerController and/or a more standard way to find the frame of the actual live preview?

Some code for the "CAMPreviewView" hack ...

extension UIView {

    var subviewsRecursive: [UIView] {
        return subviews + subviews.flatMap { $0.subviewsRecursive }
    }
    
    ///Find by type by string.
    func first(ofType: String) -> UIView? {
        return subviewsRecursive.first(where: {String(describing: $0).contains(ofType)})
    }
}
2
  • 1
    Your solution is really the only one. There is no public API to know the built-in preview view frame. The only possible alternative which gives you full control is to create a fully custom camera view using AVFoundation. See the AVCam demo app. Commented Dec 23, 2023 at 1:41
  • I think you're right, @HangarRash - perhaps you should put it in as an answer (a negative result is very useful here). It would help googlers, I bet .. Commented Dec 23, 2023 at 20:50

1 Answer 1

0

For the record, there is really no way to achieve this as of 2024.

The only real "hack" is to find the view of type

CAMPreviewView

You can easily do that with code like ...

extension UIView {
    var subviewsRecursive: [UIView] {
        return subviews + subviews.flatMap { $0.subviewsRecursive }
    }
    ///Find by type by string.
    func first(ofType: String) -> UIView? {
        return subviewsRecursive.first(where: {
           String(describing: $0).contains(ofType)
        })
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.