Creating a Full-Screen Camera Preview


I'm not big on the whole Image Picker Camera interface. I hate how slow it is and how it prevents you from scraping the screen. So here's my work around. In the following code, I scan down the UIImagePicker presentation to find my way to the actual preview window.

First, I build my camera controller. I make sure that the camera type source is available:

#define SOURCETYPE UIImagePickerControllerSourceTypeCamera
if ([UIImagePickerController isSourceTypeAvailable:SOURCETYPE])	self.sourceType = SOURCETYPE;

Next, I add a delayed call to tell the image picker to update itself. This allows time for the image picker to load before I start messing with its views. I'm using a Navigation Controller here because I need a "Snap" button as part of my interface.

CameraController *cam = [[CameraController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:cam];
[cam performSelector:@selector(updateView) withObject:NULL afterDelay:2.0f];

The update adds a bar button item to the navigation bar and removes the overlay leaving just the preview displayed:

- (void) updateView
{
	self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
											   initWithTitle:@"Snap" 
											   style:UIBarButtonItemStylePlain 
											   target:self 
											   action:@selector(snapIt:)] autorelease];
	
	// Remove the overlay
	UIView *plView = [[[[[[self.view subviews] lastObject] subviews] lastObject] subviews] lastObject];
	[[[plView subviews] objectAtIndex:3] removeFromSuperview];
}

This allows me to snap a copy of the screen as desired. This current implementation does not hide or remove the nav bar. It just does a full-screen snap:

- (void) snapIt: (UIBarButtonItem *) button
{	
    [self writeImage:[UIImage imageWithCGImage:UIGetScreenImage()]];
}

I put this all together so I could update "Dress Up" for App Store. I'm not sure, however, that removing the Apple UI elements will qualify to get past Apple's gatekeepers. What do you think? Should customizing an existing UI element like the be a bar to the store? Let me know in the comments.

AddThis Social Bookmark Button
Comments (24)

24 Comments

I believe this definitely violates the spirit of Apple's (stupid) restrictions ;P.

WiFone said:

One could actually also argue the reverse: to ensure a consistent user experience, which Apple seems to welcome or even demand, one should preferably use the same standard UI elements as Apple does.

Chris L said:

Good luck. I've heard of apps getting rejected due to lesser things, like a toolbar being at the top of the screen instead of the standard bottom.

Malcolm Hall said:

Problem here is the photo is only screen res instead of 1MP.

holly said:

It is PLCameraController instead in 2.x

Blain said:

Should customizing an existing UI element like the be a bar to the store?

You know as well as I do that Apple gets blamed when iPhone OS updates happen and applications break. So if they were to change some internal functions or layouts, that only Apple code calls, all well behaved apps will continue to run fine.

Apps that aren't well behaved, and make assumptions that are not only risky to make, but have been explicitly marked as, 'do not assume', and then hurt the experience when the assumptions no longer hold true, well, shouldn't do that.

Calling a function that is undocumented and might go away in 2.2 or 2.3 is one example of not being well-behaved. Blindly navigating and pulling objects from a view hierarchy without knowing what they are except that 'it worked when I tested it' is another.

Generating bug reports with Apple is a good way for them to know which private libraries they should clean up and make public. Placing land mines for the user by depending on an immature and rapidly changing API to not change isn't. Note the irony that, in using private frameworks, it would make Apple's job of making them open to the public harder, because now they can't rename, replace, and refactor things as easily as they should.

I'd even to go so far as saying the sample code has at least two show-stopping bugs.

Warren said:

At a recent San Francisco Tech Talk, an Apple Evangelist demonstrated how to use [[someView subviews] objectAtIndex:1] to tweak VideoPlayback . Sorry, don't have details, at the moment.

The point is, if Apple is showing how to get around their normal controls, then this may not be a show stopper, after all.

Mileage may vary.

Bruce said:

There is a new app called SteadyCam that seems to use direct camera access. Very cool app but I doubt they are following the rules.

Louis said:

I didn't get how it was supposed to work at first, but I figured it out at the end. And I moved the removing of the overlays into viewDidAppear:, so no fumbling with delays/what happens when the controller is "re-appeared".
Here's my write up about how I did it.

lajos said:

I have a small xcode project and some write up to demonstrate some tweaks to the camera interface here: custom UIImagePickerController camera view.

walt said:

I did very much the same thing for our first app, Laser Level. By trial and error I discovered which views I did not want and simply hid them rather than remove them. Apple approved it for the iTunes store, and rightly so I think because no private classes were used.

I think that hiding a view is less risky than removing it, but in either case I do agree that a future OS release could break my code. However our app does say that it requires iPhone OS 2.2 update and will remain that way until I can test Laser Level with the next OS release.

I also submitted enhancement requests to allow developers to remove/customize the big buttons and messages. If Apple's native camera app doesn't have to splash "Take Photo" (or whatever it is) across their screen I don't understand why UIImagePicker has to.

(BTW Erica, I picked up your book when I started and found it really helpful, thanks.)

Nice tips. That's exactly what I was looking for.

jacob said:

I'm not big on the whole Image Picker Camera interface. I hate how slow it is and how it prevents you from scraping the screen. So here's my work around. In the following code, I scan down the UIImagePicker presentation to find my way to the actual preview window.

Sweet SMS said:

I agree that public have to pay all this thanks for the article and its good to see people taking interest in discussion.

Gadget Blog said:

If your app gets rejected, try sending Apple your source code and demonstrate to them that you are not accessing any of the private APIs. Explain that you are merely rearranging the view by casting the classes in the view hierarchy to UIView.
www.gadget-blog.co.uk

Couplons said:

Thank you for the tutorial.

I could update "Dress Up" for App Store. I'm not sure, however, that removing the Apple UI elements will qualify to get past Apple's gatekeepers. What do you think? Should customizing an existing UI element like the be a bar to the store? Let me know in the comments.

Benalmadena said:

I'm not big on the whole Image Picker Camera interface either, but your way around is excellent, thanks.

Cini said:

I try it and I think I damaged the soft. Now it's all black, and when I push the screen it's blinking. Publicitate

the american said:

Generating bug reports with Apple is a good way for them to know which private libraries they should clean up and make public. Placing land mines for the user by depending on an immature and rapidly changing API to not change isn't. Note the irony that, in using private frameworks, it would make Apple's job of making them open to the public harder, because now they can't rename, replace, and refactor things as easily as they should.

A huge appreciation on the article that you have posted. Thanks a lot for sharing this one.

Iqor said:

These codes are very helpful for us. Thanks a lot for this. More power on this.

mani said:

I hope I can do it to the new 4gs that I just ordered. I am waiting for 3 weeks already for it to arrive at my door. It cost me quite a lot of money but they say it's worth it hostess.

dennis druft said:

Fairly great submit. I just stumbled upon your web site and wanted to say that I've actually enjoyed reading your website posts. Any way I'll be subscribing for your feed and I hope you article once again soon.