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:
(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)})
}
}
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)
})
}
}