Reputation: 18487
I am using the UIImagePickerController
class and my buttons are in the camera overlay.
I would like to adjust the orientation of my camera buttons dynamically depending on device orientation the way Apple's Camera.app does. I understand that UIImagePickerController
is portrait mode only and should not be subclassed. Still, I would like to be able to trap and respond to the device rotation viewController events.
Is there any clean way to do this? The viewController which presents the UIImagePickerController
no longer responds to events once the picker is presented.
There seem a few related questions on this topic but none that clarify if what I want to do is possible or not. Compounding confusion, there seems to be some differences with UIImagePickerController
functionality between iOS versions. I am developing this on iOS6/iPhone4 but would like to be compatible with iOS5.
Upvotes: 1
Views: 808
Reputation: 31745
Here is a clean way to do it, tested on iPhone4s/iOS5.1 and iPhone3G/iOS6.1
I am using Apple's PhotoPicker sample and making a couple of small changes. I expect you can adapt this approach for your project. The basic idea is to use notifications to trigger a method every time we rotate. If that method is in the overlay's view controller, it can carry on manipulating the overlay while the imagePicker is showing.
In OverlayViewController.m
add this into initWithNibName
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(didChangeOrientation)
name:@"UIDeviceOrientationDidChangeNotification"
object:nil];
These notifications continue to be sent while the pickerController is showing. So here, in the overlay's view controller, you can continue to play with the interface, for example:
- (void) didChangeOrientation
{
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
self.cancelButton.image =[UIImage imageNamed:@"portait_image.png"];
} else {
self.cancelButton.image =[UIImage imageNamed:@"landscape_image.png"];
}
}
you will need to kill the notification and remove the observer in viewDidUnload
:
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] removeObserver:self];
Note the way this app is designed: the overlayViewController acts like a wrapper around imagePickerController. So you invoke the imagePicker through the overlayViewController:
[self presentModalViewController:self.overlayViewController.imagePickerController animated:YES];
The overlayViewController acts as the delegate for imagePickerController, and in turn has delegate methods to relay information back to the invoking view controller.
An alternative is not to use UIImagePickerController at all, but to use AVFoundation media capture instead which gives you much more fine-grained control over the picture-taking process, at the expense of (slightly) greater complexity.
Upvotes: 1