Iphone is made up of numerous beneficial attributes. A single of them is make-in digital camera and Camera application program for creating photos. It seems to be excellent but what about digital camera use with indigenous purposes? Iphone SDK delivers the ability of applying digital camera by UIImagePickerController class. That is excellent but there is a smaller downside – you can not produce a comprehensive-screen persistent “live” digital camera perspective like the Camera application does. In its place of that you should use UIImagePickerController only in modal manner – show the pop-up modal perspective when you will need a picture and close the perspective immediately after the picture is produced. You have to reopen this perspective again to take the subsequent 1.

What’s more, that modal perspective is made up of extra panels and controls that overlay the digital camera perspective. A further downside is – you can not take a picture in 1 touch you will need to touch the Shoot button to take a picture and preview it, and then you will need to touch the Preserve button to get the picture for processing. Almost certainly it’s the finest follow but I don’t like it and I hope you feel the exact way.

What about applying the UIImagePickerController as an ordinal non-modal perspective controller below the navigation controller the exact way as we use the other perspective controllers? Consider it and you will discovered that it operates! The digital camera perspective operates and seems to be as it should. You can assign a delegate and system UIImagePickerControllerDelegate situations to get and preserve the picture. Ok, touch the Shoot button, touch the Preserve button – excellent, you’ve acquired the picture! But just seem at this – the Retake and Preserve buttons keep higher than the digital camera perspective, and they don’t operate now when they are touched… This is due to the fact you can not reset the perspective to take an additional picture immediately after getting 1 and touching the Preserve button, the perspective is freezed and the buttons are disabled. It seems you will need to totally recreate the UIImagePickerController instance to take an additional picture. That is not so basic and not so great. And you even now will need to use the panels and buttons that overlay the digital camera view…

Now I have an idea! When we touch Shoot, the perspective stops refreshing and shows solitary graphic from the digital camera then we have to touch Retake or Preserve button. Can we get that graphic and preserve it without applying the UIImagePickerControllerDelegate and then touch the Retake button programmatically to reset the perspective and get an additional picture? Positive we can! If you examine the digital camera sights hierarchy immediately after touching Shoot you will locate that there is a hidden perspective of ImageView type. This class is not described in the SDK, but we can examine its’ methods applying Goal-C abilities. We can see that the class is made up of a strategy called imageRef. Let’s check out this… Indeed, it returns CGImage object! And the graphic measurement is 1200 x 1600 – it’s certainly the digital camera picture!

Ok, now we know we can get the picture without UIImagePickerControllerDelegate. But in what second should we do this? Can we catch the person touches on the Shoot button to get started processing? It is attainable but not so great. Do you remember our principal goal – making the persistent comprehensive-screen digital camera perspective like program Camera application does? It is time to do it! When we explored the sights hierarchy, we’ve discovered that there are number of sights higher than the digital camera perspective. We can check out to hide these sights and produce our very own button below the digital camera perspective to take the picture in 1 touch. But how can we power the digital camera perspective to make the picture? It is extremely basic – we can get the corresponding selector from the Shoot button and contact it from our action handler!

Ok, we’ve pressured having the graphic. But it requires us couple of seconds. How can we detect that the graphic is ready? It happened when the Cancel and Shoot buttons are replaced by Retake and Preserve kinds. The most straightforward way to detect this is starting off a timer with brief interval and checking the buttons. And then we can get and preserve the picture, applying the corresponding selector from the Retake button and calling it to reset the digital camera perspective and prepare it for creating a new 1. In this article is the code:

// Shot button on the toolbar touched. Make the picture.
– (void)shotAction:(id)sender
[self enableInterface:NO]
// Simulate touch on the Impression Picker’s Shot button
UIControl *camBtn = [self getCamShutButton]
[camBtn sendActionsForControlEvents:UIControlEventTouchUpInside]

// Set up timer to look at the digital camera controls to detect when the graphic
// from the digital camera will be organized.
// Impression Picker’s Shot button is handed as userInfo to compare with recent button.
[NSTimer scheduledTimerWithTimeInterval:.2 goal:self selector:@selector(savePhotoTimerFireMethod:) userInfo:camBtn repeats:NO]

// Return Impression Picker’s Shoot button (the button that would make the picture).
– (UIControl*) getCamShutButton

UIView *topView = [self findCamControlsLayerView:self.perspective]
UIView *buttonsBar = [topView.subviews objectAtIndex:2]
UIControl *btn = [buttonsBar.subviews objectAtIndex:one]

return btn

// Return Impression Picker’s Retake button that seems immediately after the person pressed Shoot.
– (UIControl*) getCamRetakeButton

UIView *topView = [self findCamControlsLayerView:self.perspective]
UIView *buttonsBar = [topView.subviews objectAtIndex:2]
UIControl *btn = [buttonsBar.subviews objectAtIndex:]

return btn

// Find the perspective that is made up of the digital camera controls (buttons)
– (UIView*)findCamControlsLayerView:(UIView*)perspective

Course cl = [perspective class]
NSString *desc = [cl description]
if ([desc compare:@”PLCropOverlay”] == NSOrderedSame)
return perspective

for (NSUInteger i = i < [view.subviews count] i++) UIView *subView = [perspective.subviews objectAtIndex:i]
subView = [self findCamControlsLayerView:subView]
if (subView)
return subView

return nil

// Termed by the timer. Check the digital camera controls to detect that the graphic is ready.
– (void)savePhotoTimerFireMethod:(NSTimer*)theTimer

// Examine recent Impression Picker’s Shot button with handed.
UIControl *camBtn = [self getCamShutButton]
if (camBtn != [theTimer userInfo])

// The button replaced by Preserve button – the graphic is ready.
[self saveImageFromImageView]

// Simulate touch on Retake button to continue functioning the digital camera is ready to take new picture.
camBtn = [self getCamRetakeButton]
[camBtn sendActionsForControlEvents:UIControlEventTouchUpInside]

[self enableInterface:Indeed]


NSTimeInterval interval = [theTimer timeInterval]
[NSTimer scheduledTimerWithTimeInterval:interval goal:self selector:@selector(savePhotoTimerFireMethod:) userInfo:camBtn repeats:NO]

// Preserve taken graphic from hidden graphic perspective.
– (BOOL)saveImageFromImageView

UIView *cameraView = [self.perspective.subviews objectAtIndex:]
if ([self enumSubviewsToFindImageViewAndSavePhoto:cameraView])
return Indeed

return NO

// Recursive enumerate subviews to locate hidden graphic perspective and preserve picture
– (BOOL)enumSubviewsToFindImageViewAndSavePhoto:(UIView*)perspective

Course cl = [perspective class]
NSString *desc = [cl description]
if ([desc compare:@”ImageView”] == NSOrderedSame)
return [self grabPictureFromImageView:perspective]

for (int i = i < [view.subviews count] i++) if ([self enumSubviewsToFindImageViewAndSavePhoto:[perspective.subviews objectAtIndex:i]])
return Indeed

return NO

// Get the graphic from hidden graphic perspective and preserve the picture
– (BOOL)grabPictureFromImageView:(UIView*)perspective

CGImageRef img = (CGImageRef)[perspective imageRef]
if (img)

// Taken graphic is in UIImageOrientationRight orientation
UIImage *picture = [self correctImageOrientation:img]
UIImageWriteToSavedPhotosAlbum(picture, nil, nil, nil)

return Indeed

return NO

// Right graphic orientation from UIImageOrientationRight (rotate on 90 levels)
– (UIImage*)correctImageOrientation:(CGImageRef)graphic

CGFloat width = CGImageGetWidth(graphic)
CGFloat top = CGImageGetHeight(graphic)
CGRect bounds = CGRectMake(.0f, .0f, width, top)

CGFloat boundHeight = bounds.measurement.top
bounds.measurement.top = bounds.measurement.width
bounds.measurement.width = boundHeight

CGAffineTransform rework = CGAffineTransformMakeTranslation(top, .0f)
rework = CGAffineTransformRotate(rework, M_PI / 2.0f)


CGContextRef context = UIGraphicsGetCurrentContext()

CGContextScaleCTM(context, – one.0f, one.0f)
CGContextTranslateCTM(context, -top, .0f)
CGContextConcatCTM(context, rework)

CGContextDrawImage(context, CGRectMake(.0f, .0f, width, top), graphic)

UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext()


return imageCopy

A further essential question is: in what second can we hide the overlaying digital camera sights and controls and produce our very own button? Attempting the viewDidLoad… Oops… The digital camera perspective is even now not produced. Attempting the viewWillAppear… The exact thing… Attempting the viewDidAppear… Indeed, the sights have been produced and can be hidden now. Ok, we hide that and produce a toolbar with our Shoot button. It operates, but the screen flicks – we see how the typical sights and buttons are shown and then hidden. How can we stop this? I experimented with a number of methods and experienced discovered the finest 1: we should hide the sights right before they are additional to the digital camera perspective (when the addSubview strategy of the digital camera perspective is called). It is attainable applying Goal-C ability to exchange the strategy dynamically at operate-time. Ok, let us exchange the addSubview by our very own strategy. In our strategy we can look at that the handed perspective is 1 of the digital camera perspective subviews and established its’ “hidden” house to Indeed. So, we exchange the addSubview in the viewWillAppear right before the digital camera perspective is produced. And we produce our toolbar and Shoot button in the viewDidAppear immediately after the digital camera perspective is produced. Get a seem at the code below:

// Switch “addSubview:” if called initial time hide digital camera controls normally.
– (void)viewWillAppear:(BOOL)animated {

[tremendous viewWillAppear:animated]

if (toolBar != nil)
// The perspective was by now appeared we you should not will need to subclass UIView
// but will need to hide more digital camera controls.
UIView *cameraView = [self findCamControlsLayerView:self.perspective]
if (cameraView)

cameraView = cameraView.superview
int cnt = [cameraView.subviews rely]
if (cnt >= 4)

for (int i = 2 i < cnt - 1 i++) UIView *v = [cameraView.subviews objectAtIndex:i]
v.hidden = Indeed


// Subclass UIView and exchange addSubview to hide the digital camera perspective controls on fly.
[RootViewController exchangeAddSubViewFor:self.perspective]


// Exchange addSubview: of UIView class established our very own myAddSubview as a substitute
+ (void)exchangeAddSubViewFor:(UIView*)perspective

SEL addSubviewSel = @selector(addSubview:)
System originalAddSubviewMethod = class_getInstanceMethod([perspective class], addSubviewSel)

SEL myAddSubviewSel = @selector(myAddSubview:)
System replacedAddSubviewMethod = class_getInstanceMethod([self class], myAddSubviewSel)

strategy_exchangeImplementations(originalAddSubviewMethod, replacedAddSubviewMethod)

// Add the subview to perspective “self” points to the mother or father perspective.
// Set “hidden” to Indeed if the subview is the digital camera controls perspective.
– (void) myAddSubview:(UIView*)perspective

UIView *mother or father = (UIView*)self

BOOL carried out = NO
Course cl = [perspective class]
NSString *desc = [cl description]

if ([desc compare:@”PLCropOverlay”] == NSOrderedSame)

for (NSUInteger i = i < [view.subviews count] i++) UIView *v = [perspective.subviews objectAtIndex:i]
v.hidden = Indeed

carried out = Indeed

[RootViewController exchangeAddSubViewFor:mother or father]

[mother or father addSubview:perspective]

if (!carried out)
[RootViewController exchangeAddSubViewFor:mother or father]

The procedure described higher than was applied in iUniqable application obtainable from Apple App Retail outlet (Social Networking part). Really feel no cost to use.

Really feel no cost to stop by the website of the developer www.enterra-inc.com