Hiding the "Take Picture" overlay
One of the annoying thing with the default UIImagePickerController is the “Take Picture” overlay. This article is about removing that useless piece of UI.

Rant: The iphone screen is small, i don’t really understand the role of that huge “Take Picture” caption. It’s hard to imagine any case where the user needs this information.
Finding the UIView to hide
Obviously that element is an UIView and once we find it it should be easy to hide it. But how do we find it? One way to do it is dumping the view hierarchy with dimensions and then location the view in question based on it’s size/position.
The following code can be used to dump the view hiearachy with the dimensions:
- (void)dumpViews:(NSString*)pre view:(UIView*) view
{
NSLog(@"%@View:%@ [%.f,%.f,%.f,%.f]\n",pre,view,
view.frame.origin.x,view.frame.origin.y,
view.frame.size.width,view.frame.size.height);
for(UIView *sview in view.subviews) {
[self dumpViews:[NSString stringWithFormat:@" %@",pre]
view:sview];
}
}
We’ll call it like [self dumpViews:@"" view:rootView];. We only need to find out the rootView, and the right time to call it. We need to call it after the elements are created but before they are displayed.
Finding a container view
Once the image picker view is visible, we should be able to use window as the rootView, but again we want to remove it before it’s displayed. We can try using UIImagePickerController view property, but that will be empty just after creation. So we need to find the right point – after the creation, but before the display.
The solution is to realize that UIImagePickerController is an UINavigationController. Navigation controllers will notify delegates before it displays a new view controller via: - (void)navigationController:willShowViewController:animated:(BOOL)animated.
- (void)navigationController:(UINavigationController *)nav
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
[self dumpViews:@"" view:viewController.view];
}
We get the following output:
navigationController:<UIImagePickerController>
willShowViewController:<PLCameraViewController>
View:<UIView: 0x5296a0> [0,0,320,480]
View:<PLCameraView: 0x52ec40> [0,0,320,480]
View:<UIImageView: 0x532380> [10000,10000,320,480]
View:<UIView: 0x5372e0> [0,480,320,0]
View:<PLCropOverlay: 0x529ce0> [0,0,320,480]
View:<UIImageView: 0x528540> [0,20,320,96]
View:<PLCropLCDLayer: 0x5285d0> [0,20,320,96]
View:<TPBottomDualButtonBar: 0x535290> [0,384,320,96]
View:<TPPushButton: 0x535450> [22,26,128,47]
View:<TPCameraPushButton: 0x537900> [170,26,128,47]
View:<UIImageView: 0x5372b0> [51,12,26,19]
From the dimensions it’s easy to see that what we want to hide is: UIImageView and PLCropLCDLayer:
View:<UIImageView: 0x528540> [0,20,320,96]
View:<PLCropLCDLayer: 0x5285d0> [0,20,320,96]
Hiding the overlay
The challenge with hiding the “Take Picture” overlay is that we want to make sure we’re only hiding the right elements. We don’t want to get into a situation where we’re hiding the buttons instead of the overlay.
The following code makes sure that we’re hiding the correct elements by checking their dimensions:
- (void)hideTakePhotoCaption:(UIViewController*)viewController
{
if (viewController.view.subviews.count > 0) {
UIView* cameraView = [viewController.view.subviews
objectAtIndex:0];
if (cameraView.subviews.count > 2) {
UIView* cropOverlay = [cameraView.subviews lastObject];
if (cropOverlay.subviews.count > 1) {
UIView* imageView = [cropOverlay.subviews
objectAtIndex:0];
UIView* view2 = [cropOverlay.subviews objectAtIndex:1];
if (imageView.frame.size.height == 96.0 &&
view2.frame.size.height == 96.0) {
imageView.hidden = YES;
view2.hidden = YES;
}
}
}
}
}
- (void)navigationController:(UINavigationController *)nav
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
{
[self hideTakePhotoCaption:viewController];
}
We could add even more checks by making sure the items we hide has the right type (class), but that is left as an excercise for the reader.
Adding your UI elements to the camera screen.
Note that the techinque described above is not limited to hiding the overlay. You can add your own overlay as well.