views:

943

answers:

2

I have designed an iris shutter animation for a camera view in an iPhone app.

Unfortunately, it seems impossible to hide Apple's shutter when the view appears, even if I hide the camera controls and create a custom cameraOverlayView.

I have gotten around this by animating my shutter on top of the normal shutter when the view appears, using the viewWillAppear and viewDidAppear methods of UIImagePickerController. However, I can't get the shutter to be hidden under my shutter the first time through. When the app launches, it shows a camera view, and the original shutter is visible. On all subsequent views of the cameraController, my workaround works. Any suggestions?

Here's my code. This is from my app delegate:

- (void)applicationDidFinishLaunching:(UIApplication *)application {   

  cameraController = [[CameraController alloc] initWithMode:@"camera"];
  [window addSubview:cameraController.view];

}

And this is from my UIImagePickerController subclass:

- (void) viewWillAppear:(BOOL)animated {

  if (self.sourceType != UIImagePickerControllerSourceTypePhotoLibrary || simulatorView) {
    [self addShutter];
    [shutter close];
  }   
  [super viewWillAppear:animated];

}


- (void) viewDidAppear:(BOOL)animated {

  if (self.sourceType != UIImagePickerControllerSourceTypePhotoLibrary || simulatorView) {
    [shutter openShutter:.5f];
  }
  [super viewDidAppear:animated];

}
A: 

Note that the docs say that subclassing UIImagePickerController isn't supported, so it may work in some cases but isn't "safe". Not sure if it would get rejected by the app store. (Probably depends on how picky their static code verification tool is.)

I don't really have a good answer, but you might try either 1) iterating over the subviews of the picker's main view to see if you can identify whatever is being used to animate the shutter, then mangle it so that it won't display, or 2) for the initial animation, just show the initial image picker main view under another opaque black view. Not sure if the user-specified overlay view would work for that or not, but you might be able to do those without subclassing.

Searching for undocumented subviews is another thing that's theoretically unsafe though since who knows how the implementation might change in the future.

Nimrod
I don't think the docs say that anywhere, and I have multiple apps with UIImagePickerController subclasses. Apple even provides .cameraOverlayView to help you do it in 3.0.
Andrew Johnson
The docs DO say that you aren't supposed to subclass it:From the UIImagePickerController Class Reference:"Important: The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified, with one exception. In iPhone OS 3.1 and later, you can assign a custom view to the cameraOverlayView property and use that view to present additional information or manage the interactions between the camera interface and your code."
Nimrod
And why did someone vote me down for that answer? I was correct about what the docs say.
Nimrod
I downvoted you myself because suggesting iteration over the subviews is a no no in 3.0, as the docs you posted say.
Andrew Johnson
A: 

Hi!

Possibly too late, but my proposal is to use the following notifications (found while debugging)

  1. PLCameraControllerAvailable - camera controller object is initiated, but shutter is not visible yet
  2. PLCameraViewIrisAnimationDidEndNotification - iris animation is completed.

And the usage is straightforward: call UIGetScreenImage() on 1st notification, render grabbed image on screen (fullscreen) just above the UIImagePicker. Destroy rendered image on the 2nd notification.

Thanks for your answer, but I can't ue private calls. This is for a client's app :)
Andrew Johnson
Well. What's regarding UIGetScreenImage() - Apple has officialy allowed to use that undocumented function:http://www.tuaw.com/2009/12/15/apple-relents-and-is-now-allowing-uigetscreenimage-for-app-st/