I am using this code in my button action function:
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.allowsEditing = NO;
picker.wantsFullScreenLayout = YES;
[self presentViewController:picker animated:YES completion:nil];
I am implementing the delegate also. UIImagePickerControllerDelegate
But it gets crashed at
[self presentViewController:picker animated:YES completion:nil];
Can som one help me out on what I am doing wrong?
This is for IOS 6. These delegate methods are supported only in IOS 6.
I got the answer to my own question. My application was developed for landscape mode only. So the imagePickerView was not able to present itself as its default orientation is landscape. So I made my application supported for landscape and portrait mode. In the app delegate I used the method,
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
return UIInterfaceOrientationMaskAll;
else /* iphone */
return UIInterfaceOrientationMaskAllButUpsideDown;
}
And in the rootViewController I used the following delegates to force the viewController to be in landscape mode and remain in landscape mode.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationLandscapeRight)
return YES;
else
return NO;
}
- (BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}
And it worked.
Related
Edit - I solved this myself - see the notes at the bottom
When using iOS7 on Xcode 5, I am using an option to take an image from a camera, or from the photo library, once the image is chosen (or a new picture taken) the view should flip over to the next screen.
This does not happen on the iPhone running iOS7, it works fine on the iPad, but the method is slightly different, but it does appear to be iPhone only problem on iOS7.
here is the code used, for example, on the choose image from library function;
-(void) choosePic {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]) {
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
cameraUI.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeSavedPhotosAlbum];
cameraUI.allowsEditing = NO;
cameraUI.delegate = self;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
_popover = [[UIPopoverController alloc] initWithContentViewController:cameraUI];
[_popover presentPopoverFromRect:btnLibrary.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else
[self presentModalViewController: cameraUI animated: YES];
}
}
Also, the code once picker is finished;
- (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary *) info {
//Disable buttons
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self disableButtons];
//Get image
self.originalImage = (UIImage *) [info objectForKey: UIImagePickerControllerOriginalImage];
//Dismiss
if(_popover)
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
[_popover dismissPopoverAnimated:YES];
_popover = nil;
}
}
else
[picker dismissModalViewControllerAnimated: YES];
//Next
[self performSelector: #selector(nextScreen) withObject:nil afterDelay:0.5];
}
I fixed this by switching out;
[picker dismissModalViewControllerAnimated: YES];
With
[picker dismissViewControllerAnimated:NO completion:nil];
First you need to make sure that logic reaches the correct place it's intended to, try setting a breakpoint or NSLog before the iPhone's specific line, try this (You also missed curled braces, added them here) :
-(void) choosePic {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum]) {
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
cameraUI.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType: UIImagePickerControllerSourceTypeSavedPhotosAlbum];
cameraUI.allowsEditing = NO;
cameraUI.delegate = self;
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
_popover = [[UIPopoverController alloc] initWithContentViewController:cameraUI];
[_popover presentPopoverFromRect:btnLibrary.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}else{
NSLog(#"Checkpoint !");
[self presentModalViewController: cameraUI animated: YES];
}
} }
I am developing an app in which i need to keep open full screen camera open and also add a button on it(bottom right). I googled but couldn't find any healthy solution. Thanks in advance. Have a good day.
Edited
- (void) showCameraUI {
[self startCameraControllerFromViewController: self
usingDelegate: self];
}
- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
usingDelegate: (id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>) delegate {
if (([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera] == NO)
|| (delegate == nil)
|| (controller == nil))
return NO;
NSLog(#"Start Camera Controller method...");
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
// Displays a control that allows the user to choose picture or
// movie capture, if both are available:
cameraUI.mediaTypes =
[UIImagePickerController availableMediaTypesForSourceType:
UIImagePickerControllerSourceTypeCamera];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
[controller presentModalViewController: cameraUI animated: YES];
return YES;
}
P.S: I also added UINavigationControllerDelegate,UIImagePickerControllerDelegate as protocol in header file, but its not still opening camera and show me default view of project.
you can simply capture image Using camera like bellow, i am using this bellow method in my code:-
-(void)btnCemeraOpen
{
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissModalViewControllerAnimated:YES];
yourImageView.image = [info valueForKey:#"UIImagePickerControllerOriginalImage"];
if(yourImageView==nil)
{
}
else
{
//DO logic
}
return;
}
Code:
HDComposeViewController *vc = [[HDComposeViewController alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
nav.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentModalViewController:nav animated:YES];
The present modal view can't rotate while device rotated. If I change modalPresentationStyle to UIModalPresentationFormSheet, it works!!!
HDComposeViewController has already implement rotate delegate:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (BOOL)shouldAutorotate
{
return YES;
}
Is there anything wrong? Thanks.
You need to add a category for navigation controlller to rotate in ios 6.
#interface UINavigationController (RotationAll)
-(NSUInteger)supportedInterfaceOrientations;
#end
#implementation UINavigationController (RotationAll)
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
#end
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
I am using MBProgressHud to show a loading indicator on a splash view but this does not change with device orientation. My code is:
splashView = [[UIImageView alloc] initWithFrame:self.window.frame];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
splashView.image = [UIImage imageNamed:#"DefaultPad.png"];
}
else
{
splashView.image = [UIImage imageNamed:#"Default.png"];
}
hud = [[MBProgressHUD alloc]initWithView:splashView];
[splashView addSubview:hud];
hud.userInteractionEnabled=NO;
hud.labelText = #"Loading...";
[hud show:YES];
[self.window addSubview:splashView];
[self performSelector:#selector(Load_FirstView) withObject:nil afterDelay:3];
[self.window makeKeyAndVisible];
and I have changed the line in MBProgressHud.m file from
- (void)deviceOrientationDidChange:(NSNotification *)notification {
NSLog(#"in device orientation ");
UIView *superview = self.superview;
if (!superview) {
return;
} else if ([superview isKindOfClass:[UIWindow class]]) { // here changes have done
[self setTransformForCurrentOrientation:YES];
} else {
self.bounds = self.superview.bounds;
[self setNeedsDisplay];
}
}
to:
- (void)deviceOrientationDidChange:(NSNotification *)notification {
NSLog(#"in device orientation ");
UIView *superview = self.superview;
if (!superview) {
return;
} else if ([superview isKindOfClass:[UIImageView class]]) {
[self setTransformForCurrentOrientation:YES];
} else {
self.bounds = self.superview.bounds;
[self setNeedsDisplay];
}
}
How can I get the loading indicator to rotate with device orientation?
In MBProgressHUD.m I changed
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
to
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
The orientation notification had been received, but the statusBar had not rotated yet.
Try This:-
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
//code for portrait
[hud release];
hud = [[MBProgressHUD alloc]initWithView:splashView];
}
else
{
//code for Landscape
[hud release];
hud = [[MBProgressHUD alloc]initWithView:splashView];
}
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
if it does not work..
you can change the UIDeviceOrientationDidChangeNotification with UIApplicationDidChangeStatusBarOrientationNotificationin the source code of MBProgressHUD:-
- (id)initWithView:(UIView *)view {
// Let's check if the view is nil (this is a common error when using the windw initializer above)
if (!view) {
[NSException raise:#"MBProgressHUDViewIsNillException"
format:#"The view used in the MBProgressHUD initializer is nil."];
}
id me = [self initWithFrame:view.bounds];
// We need to take care of rotation ourselfs if we're adding the HUD to a window
if ([view isKindOfClass:[UIWindow class]]) {
[self setTransformForCurrentOrientation:NO];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(deviceOrientationDidChange:)
name:UIDeviceOrientationDidChangeNotification object:nil];
return me;
}
In the above code change UIDeviceOrientationDidChangeNotificationwith UIApplicationDidChangeStatusBarOrientationNotification.
It is just a work-around as rotation issue was always there with MBProgressHud .
I Guess MBProgressHud is giving a lo of problems , you should instead switch to svprogresshud as it handles orientations well
didAnimateFirstHalfOfRotationToInterfaceOrientation is deprecated in iOS 5.0. However I would like to use this method in my application. I am using the sample code that Apple offers in the iOS Dev Center, project name AlternateViews. I would like the app to rotate the portraitView while fading in the landscapeView. Can this be done in iOS 5 or is this feature forever gone?
portraitView currently calls:
[self presentModalViewController:self.landscapeViewController animated:YES];
while landscapeView calls this in code in the init method:
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
It appears all of the animation is done in the following PortraitViewController.m:
#import "PortraitViewController.h"
#import "LandscapeViewController.h"
#implementation PortraitViewController
#synthesize landscapeViewController;
- (void)viewDidLoad
{
self.view.backgroundColor = [UIColor colorWithRed:197.0/255.0 green:204.0/255.0 blue:211.0/255.0 alpha:1.0];
LandscapeViewController *viewController = [[LandscapeViewController alloc]
initWithNibName:#"LandscapeView" bundle:nil];
self.landscapeViewController = viewController;
[viewController release];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)viewDidUnload
{
self.landscapeViewController = nil;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
[landscapeViewController release];
[super dealloc];
}
- (void)orientationChanged:(NSNotification *)notification
{
// We must add a delay here, otherwise we'll swap in the new view
// too quickly and we'll get an animation glitch
[self performSelector:#selector(updateLandscapeView) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
[self presentModalViewController:self.landscapeViewController animated:YES];
isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
[self dismissModalViewControllerAnimated:YES];
isShowingLandscapeView = NO;
}
}
// override to allow orientations other than the default portrait orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait); // support only portrait
}
#end
Here is my current implementation files which fail miserably.
PortraitViewController.m:
#import "PortraitViewController.h"
#import "LandscapeViewController.h"
#implementation PortraitViewController
#synthesize landscapeViewController;
- (void)viewDidLoad
{
LandscapeViewController *viewController = [[LandscapeViewController alloc]
initWithNibName:#"LandscapeView" bundle:nil];
self.landscapeViewController = viewController;
[viewController release];
NSLog(#"Portrait viewDidLoad");
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
}
- (void)viewDidUnload
{
self.landscapeViewController = nil;
}
- (void)dealloc
{
[landscapeViewController release];
[super dealloc];
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
NSLog(#"Portrait-willAnimateRotationToInterfaceOrientation Portrait");
} else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"Portrait-willAnimateRotationToInterfaceOrientation Landscape");
}
[self performSelector:#selector(updateLandscapeView) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView)
{
NSLog(#"Portrait-present Landscape");
[self presentModalViewController:self.landscapeViewController animated:YES];
isShowingLandscapeView = YES;
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
NSLog(#"Portrait-dismiss Landscape");
[self dismissModalViewControllerAnimated:YES];
isShowingLandscapeView = NO;
}
}
// override to allow orientations other than the default portrait orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
return NO;
else
return YES;
}
#end
LandscapeViewController.m
#import "LandscapeViewController.h"
#implementation LandscapeViewController
// the designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
self.wantsFullScreenLayout = YES; // we want to overlap the status bar.
// when presented, we want to display using a cross dissolve
self.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
}
return self;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
oldStatusBarStyle = [[UIApplication sharedApplication] statusBarStyle];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:NO];
NSLog(#"Landscape viewWillAppear");
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:oldStatusBarStyle animated:NO];
}
// override to allow orientations other than the default portrait orientation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// return YES for supported orientations
if (interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
return NO;
else
return YES;
//return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
NSLog(#"Landscape-willAnimateRotationToInterfaceOrientation Portrait");
[self dismissModalViewControllerAnimated:YES];
} else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
NSLog(#"Landscape-willAnimateRotationToInterfaceOrientation Landscape");
}
}
#end
In Apple's UIViewController reference page, you'll find this useful paragraph in the "Handling View Rotations" section:
If you want to perform custom animations during an orientation change,
you can do so in one of two ways. Orientation changes used to occur in
two steps, with notifications occurring at the beginning, middle, and
end points of the rotation. However, in iOS 3.0, support was added for
performing orientation changes in one step. Using a one-step
orientation change tends to be faster than the older two-step process
and is generally recommended for any new code.
To add animations for an orientation change, override the
willAnimateRotationToInterfaceOrientation:duration: method and perform
your animations there.
Could you override the willAnimateRotationToInterfaceOrientation: method to do your animations?