UIModalViewController and UIImagePickerController rotation issue - ipad

This is the situation:
I've a viewController that was presented in this way:
AddAttachmentPhotoVideoViewController * addAttachment = [[AddAttachmentPhotoVideoViewController alloc]initWithNibName:nil bundle:nil attachmentType:AtImage];
addAttachment.modalPresentationStyle = UIModalPresentationFormSheet;
addAttachment.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
           
[self presentModalViewController:addAttachment animated:YES];
in addAttachment there is a button that open the camera in this way:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;    
imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *) kUTTypeImage, nil];
imagePicker.allowsEditing = NO;
imagePicker.showsCameraControls = YES;
imagePicker.modalPresentationStyle = UIModalPresentationFullScreen;
imagePicker.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:imagePicker animated:YES];
The issue is the following: when I rotate the device (iPad) the imagePicker rotates itself but the addAttachment doesn't rotate; so when I dismiss the picker the addAttachment has a wrong frame and it's not rotate properly.
In other words, when the camera is shown, the modal view controller under it, doesn't receive the rotation and so, when I dismiss the picker, the frame of view controller is totally wrong.
Thanks...

You must handle the rotation of your ViewController manually.
The foreground ViewController should propagate the rotation message to all ViewControllers behind of it.

You have to tell the AddAttachmentPhotoVideoViewController that it should auto-rotate to all interface orientations. By default, YES is only returned for portrait orientation. Add the following method to allow auto-rotation to all orientations:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}

Related

UIViewController landscape orientation changes when Camera is opened in portrait mode

My iPad application is in Landscape. From ViewController1 I presented ViewController2. From there when camera is opened with UIImagePicker (while keeping the device in portrait mode), ViewController2 moves down a little bit and we can see ViewController1 got rotated to portrait.
Code:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
BOOL hasCamera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
if (hasCamera){
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.showsCameraControls = NO;
UIView *overlayView = [SCFUtility cameraOverlayViewForBounds:imagePicker.view.bounds withShapeRect:CGSizeMake(400, 560) target:self];
imagePicker.cameraOverlayView = overlayView;
[overlayView addSubview:self.cameraTimerLabel];
}
else
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
if (imagePicker.sourceType == UIImagePickerControllerSourceTypeCamera) {
if( [UIImagePickerController isCameraDeviceAvailable: UIImagePickerControllerCameraDeviceFront ])
{
imagePicker.cameraDevice=UIImagePickerControllerCameraDeviceFront;
}
[self.cameraTimerLabel setText:#"9"];
self.cameraCountDownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(cameraCountDownTimerTriggered:) userInfo:nil repeats:YES];
}
else{
imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.popoverPresentationController.sourceView = self.addPhotoContainerView;
imagePicker.popoverPresentationController.sourceRect = self.addPhotoContainerView.bounds;
}
[self presentViewController:imagePicker animated:YES completion:nil];
self.imagePickerController = imagePicker;
I would suggest you put a breakpoint in following callback methods (ViewController2 and ViewController1) for size change and trait collection change:
viewWillTransitionToSize:withTransitionCoordinator:
traitCollectionDidChange
And find out what is triggering rotation or view size changes.

iOS, PopOverPresentationController issue, .xib

I have a NavigationController, another controller was pushed on its stack: BNRDetailsViewController. Now, inside BNRDetailsViewController I am trying to show a popover window when pressing on a toolbar button, that would present me with UIImagePickerController (only on iPad devices). So, I tried to follow the following stackoverflow thread:
UIPopoverPresentationController on iOS 8 iPhone
But no success. If I just use their code I get an error that says, that pushing navigationController is not supported. If I try to push the newly created UIPopoverPresentationController like this: [self.navigationController pushViewController:self.imagePickerPopover animated:YES]; it crashes because UIPopoverPresentationController is not of type UIViewController, so, I guess, I can not just push it on the stack.
What would you suggest to do in this particular case?
Here is the code which I have right now that is triggered when the toolbar button is pressed:
- (IBAction)takePicture:(id)sender {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// If the device have camera, take a picture, otherwise,
// just pick from photo library
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
} else {
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
imagePicker.delegate = self;
// Place image picker on the screen
//[self presentViewController:imagePicker animated:YES completion:NULL];
// Place image picker on the screen
// Check for iPad device before instantiating the popover controller
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
// Create a new popover controller that will display the imagePicker
_imagePickerPopover = [[UIPopoverPresentationController alloc] initWithPresentedViewController:imagePicker presentingViewController:self];
imagePicker.preferredContentSize = CGSizeMake(280, 200);
_imagePickerPopover.delegate = self;
_imagePickerPopover.sourceView = self.view;
CGRect frame = [[sender valueForKey:#"view"] frame];
frame.origin.y = frame.origin.y + 20;
_imagePickerPopover.sourceRect = frame;
// [self.navigationController pushViewController:self.imagePickerPopover animated:YES];
}
}
Here is the code, based on your code, that will get the popover to display on the iPad.
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.preferredContentSize = CGSizeMake(280, 200);
CGRect frame = [[sender valueForKey:#"view"] frame];
frame.origin.y = frame.origin.y + 20;
UIPopoverPresentationController *popoverController =
imagePicker.popoverPresentationController;
popoverController.sourceView = self.view;
popoverController.sourceRect = frame;
[self.navigationController presentViewController:imagePicker
animated:YES completion:nil];
}

Can't present imagepicker immediately

I have a Tab bar controller, when I tap the third tab bar button I present a UIViewcontroller. In the viewWillAppear of this vc I'm presenting a UIImagepickerController that works fine. The problem is I can't display it on the screen immediately when I open the view. First the vc shows up and after 0.4-0.5 sec the image picker. So I would like to present the image picker first and present the vc after the user took an image. I tried to call the picker from viewDidLoad and viewWillAppear too, but nothing changed.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (imagePickerWasPresented == NO)
{
imagePickerWasPresented = YES;
self.imagePicker = [[UIImagePickerController alloc] init];
self.imagePicker.delegate = self;
self.imagePicker.allowsEditing = YES;
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
[self presentViewController:self.imagePicker animated:NO completion:nil];
}
}
Am I calling it in a wrong place?
I had the same problem - instead of calling the VC and then the UIImagePicker, call the UIImagePicker directly.
When you are done taking a picture/video:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {}
you will go to this standard delegate method, call the VC from here. This way you will immediately go to the ImagePicker and only have a transition would you choose to do something with the taken content afterwards which is less frustrating/ugly.
No, your calling it in an okay place, that's just how iOS does it; if you present multiple modals on top of each other, one gets presented after the other, including the animation. A solution that would work for your problem is to present a UINavigationController instead of your UIViewController. Set the navigation controller up to have ViewController as the root viewcontroller, but also push your imagepickercontroller onto the stack. Present this navigationcontroller and it should go right to your imagepickercontroller. Otherwise, try presenting both uiviewcontroller and imagepickercontroller with animation set to NO and see if that works.
try this to see how close that gets you then adapt to your needs. when i gave it a quick test it seemed to do what you were asking.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] ;
UIViewController * vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
UINavigationController * navigationController = [[UINavigationController alloc] init];
[navigationController pushViewController:vc animated:NO];
UITabBarController * tabBarController = [[UITabBarController alloc] init];
NSArray* controllers = [NSArray arrayWithObjects:navigationController, nil];
tabBarController.viewControllers = controllers;
tabBarController.delegate = self;
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
nil];
imagePicker.allowsEditing = NO;
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
[vc presentViewController:imagePicker animated:NO completion:nil];
return YES;
}
UIImage as a PopOver
Gallery mode:
BOOL hasGallery = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary];
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = hasGalleryt ? UIImagePickerControllerSourceTypePhotoLibrary : UIImagePickerControllerSourceTypePhotoLibrary;
if (self.popoverController != nil)
{
[self.popoverController dismissPopoverAnimated:YES];
self.popoverController=nil;
}
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:picker];
CGRect popoverRect = [self.view convertRect:[self.imageView frame]
fromView:[self.imageView superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 300) ;
popoverRect.origin.x = popoverRect.origin.x;
[self.popoverController
presentPopoverFromRect:popoverRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
Camera mode:
BOOL hasCamera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
UIImagePickerController* picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = hasCamera ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypePhotoLibrary;
if (self.popoverController != nil)
{
[self.popoverController dismissPopoverAnimated:YES];
self.popoverController = nil;
}
self.popoverController = [[UIPopoverController alloc] initWithContentViewController:picker];
CGRect popoverRect = [self.view convertRect:[self.imageView frame]
fromView:[self.imageView superview]];
popoverRect.size.width = MIN(popoverRect.size.width, 300) ;
popoverRect.origin.x = popoverRect.origin.x;
[self.popoverController
presentPopoverFromRect:popoverRect
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
Remember to give to the .h File #interface the delegates, like this:
#interface the UIViewController: UIViewController <UIPopoverControllerDelegate, UIImagePickerControllerDelegate>

How to Make UIImagePicker full screen with popover controller for ipad

I have seen other posts on this subject, but no valid solutions. Surely this is possible! I found one solution here that suggests presenting it from a container view controller. The code for that is commented out in my method below. This DOES create the fullscreen view, but the cancel/take photo buttons won't work then, and I can't seem to dismiss it properly. Is there really no simple elegant solution to this???? Please help! Here's my code:
-(IBAction)launchCamera:(id)sender
{
[self.popoverController dismissPopoverAnimated:YES];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
//fullScreenViewController = [[UIViewController alloc] init];
//fullScreenViewController.contentSizeForViewInPopover = CGSizeMake(768, 1024);
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Tried making the view full screen (or at least larger), but doesn't work...
//popoverController.contentViewController.contentSizeForViewInPopover = CGSizeMake(384, 512);
[imagePicker setTitle:#"camera"];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
imagePicker.delegate = self;
imagePicker.allowsEditing = NO;
//[fullScreenViewController.view addSubview:imagePicker.view];
// change imagePicker to fullScreenViewController here for full screen:
popoverController = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
[popoverController setDelegate:self];
[popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
I never could make the UIImagePicker work properly in full-screen, so I ended up using the AVFoundation framework to implement my own.

Test ipad 2 camera with xcode simulator IOS 5

I am testing ipad camera application with ipad simulator
I used below code, change the source type instead of camera.
-(IBAction)useCamera:(id)sender{
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]){
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate =(id<UINavigationControllerDelegate,UIImagePickerControllerDelegate>) self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObjects:(NSString *) kUTTypeImage,nil];
imagePicker.allowsEditing = NO;
[self presentModalViewController:imagePicker animated:YES];
[imagePicker release];
newMedia = YES;
}
}
When it run in the simulator error came up in ios 5 simulator .
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:'On iPad, UIImagePickerController must be presented via UIPopoverController'
But its working on 4.3 simulator
Starting with iOS5 you need to show the pickercontroller in a popover view rather than a modal view.
From the apple documentation: On iPad, present the user interface using a popover. Doing so is valid only if the sourceType property of the image picker controller is set to UIImagePickerControllerSourceTypeCamera. To use a popover controller, use the methods described in “Presenting and Dismissing the Popover” in UIPopoverController Class Reference.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImagePickerController_Class/UIImagePickerController/UIImagePickerController.html
Here is an example of presenting a UIImagePickerController inside a popover view:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
[popover presentPopoverFromRect:CGRectMake(0.0, 0.0, 400.0, 400.0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];

Resources