I am trying to capture the current orientation of the UIImagePickerController being presented, and changing the overlay view's hidden property accordingly.
if([notification.name isEqualToString:#"UIDeviceOrientationDidChangeNotification"]) {
UIInterfaceOrientation orientation = self.cameraImagePicker.interfaceOrientation;
if(orientation == UIInterfaceOrientationPortrait) {
self.cameraImagePicker.cameraOverlayView.hidden = NO;
} else {
self.cameraImagePicker.cameraOverlayView.hidden = YES;
}
}
However, orientation == UIInterfaceOrientationPortrait even if I rotate the camera, but this method is called every time the device rotates.
Note: My application only supports portrait orientation according to the project file, but rotation is somehow still supported by the UIImagePickerController
Any help with this issue would be greatly appreciated!
After iOS6, apple changed the orientation API. you can try this method in your appdelegate, I hope it can help you.
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
Related
I'm having a problem with device rotation. Except for ONE view, where I show a company splash screen, I want to lock all the remaining app views into Portrait display. In the project settings the supported orientations are Portrait and LandscapeLeft. In the 'Company Splash' it works fine and the view rotation is locked into LandscapeLeft no matter how I rotate the device. On all the other views when I rotate the device to the left the view alters instead of staying in portrait display. The methods are not even firing? If I remove Landscape left from the supported Orientations in the project, that screws up the 'Company Splash' view. I tried changing the shouldAutorotate return to NO, but that didn't help. Tried to work my way through the suggestions posted here, but that didn't help. If I put the following code into my AppDelegate.m, everything is locked into portrait mode and the 'Company Splash' crashes when accessed.
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}
How do I lock the view into portrait mode no matter how the device is rotated except for the one screen?
** method from the 'Company Splash' view. Again, works like it is supposed to.
-(NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft;
}
** methods from all the other views, which rotate out of portrait when I don't want them to
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// IOS5 Only returning that it should rotate to potrait
return (interfaceOrientation == UIDeviceOrientationPortrait);
}
-(BOOL)shouldAutorotate
{
// forcing the rotate IOS6 Only
return YES;
}
-(NSInteger)supportedInterfaceOrientations
{
// return number or enum IOS6 Only
return UIInterfaceOrientationMaskPortrait;
}
I thought maybe it might be because a UITabBarController is the root controller and I'm in a ViewController off of that? The methods are not even firing?
Add an observer to the viewDidLoad method of the view you want to rotate like this :
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
and then set the views according the the landscape view inside the orientationChanged method like this :
- (void) orientationChanged:(NSNotification *)note{
UIDevice * device = [UIDevice currentDevice];
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
break;
case UIDeviceOrientationPortraitUpsideDown:
break;
case UIDeviceOrientationLandscapeLeft:
break;
case UIDeviceOrientationLandscapeRight:
break;
default:
break;
};
}
Slap this method into the view controller you want locked in a certain orientation.
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
just change to the orientation you want (the above locks it in landscape)
maybe u should allow all orientations, and lock portrait orientation in each class except company splash with
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
} else {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
}
For my app, I want to let the device rotate anyway but upside-down. This is working fine. However, I want to stop the app from rotating specifically from
landscape left -> landscape right - and vice versa
If anyone is curious, this is because that rotation messes up my layouts, as they each rotate from a common point
My code for iOS 5, which I think would work, is like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
NSLog(#"Rotating");
if((lastOrient == 3 && toInterfaceOrientation == 4) || (lastOrient == 4 && toInterfaceOrientation == 3)){
lastOrient = toInterfaceOrientation;
return NO;
}
lastOrient = toInterfaceOrientation;
return YES;
}
Where 3= landscape left and 4= landscape right
Any suggestions on how to do this with iOS6? Or a completely different solution?
shouldAutorotateToInterfaceOrientation is deprecated in ios6. Use this:
- (BOOL)shouldAutorotate {
UIInterfaceOrientation orientation = [[UIDevice currentDevice] orientation];
if (lastOrientation==UIInterfaceOrientationPortrait && orientation == UIInterfaceOrientationPortrait) {
return NO;
}
return YES;
}
Haven't tested this code. You can get more info on these posts:
shouldAutorotateToInterfaceOrientation is not working in iOS 6
shouldAutorotateToInterfaceOrientation not being called in iOS 6
Ok I answered my own question here:
The good news is, there is definitely a way to do this! So heres the basics:
In iOS6, it is up to the appDelegate to handle whether the app can rotate in general. Then, when the device gets a rotation signal, it will ask your view for its supported orientations. This is where I implemented my code. In fact, shouldAutorotate() plays no role in the solution.
So I create a variable to keep track of the last orientation, and change it in
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
This way I can compare orientations
-(NSUInteger)supportedInterfaceOrientations
{
NSLog(#"Last Orient = %d", lastOrient);
NSUInteger orientations = UIInterfaceOrientationMaskPortrait;
if (lastOrient != 3 && lastOrient != 4) {
NSLog(#"All good, rotate anywhere");
return UIInterfaceOrientationMaskAllButUpsideDown;
}
else if(lastOrient == 3){
orientations |= UIInterfaceOrientationMaskLandscapeRight;
NSLog(#"Can only rotate right");
}
else if(lastOrient == 4){
orientations |= UIInterfaceOrientationMaskLandscapeLeft;
NSLog(#"Can only rotate left");
}
return orientations;
}
Seems to work for me. Slightly a hack, but it does what it needs to do
I want to change the orientation of the app without changing the device orientation in iphone app.
I want to change my view from portraid mode to landscap mode programmatically.
And also want to know that will this be accepted by the apple store or not ?
Thanks
Now I got the solution from other that is as follow
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
when you add this line at that time one warning appear and for remove this warning just add bellow code on you implementation file..
#interface UIDevice (MyPrivateNameThatAppleWouldNeverUseGoesHere)
- (void) setOrientation:(UIInterfaceOrientation)orientation;
#end
and after that in bellow method just write this code if required..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
But now want to know is this accepted by apple app store or not ?
thanks
use this line for programmatically change orientation...
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
and also when you add this line at that time one warning appear and for remove this warning just add bellow code on you implementation file..
#interface UIDevice (MyPrivateNameThatAppleWouldNeverUseGoesHere)
- (void) setOrientation:(UIInterfaceOrientation)orientation;
#end
and after that in bellow method just write this code if required..
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
// return NO;
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
i hope this help you..
:)
Add a class variable
Bool isInLandsCapeOrientation;
in viewDidLoad
set this flag to
isInLandsCapeOrientation = false;
Add the following function
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (!isInLandsCapeOrientation) {
return (UIInterfaceOrientationIsPortrait(interfaceOrientation));
}else {
return (UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
}
To changing orientation from portrait to landscape, let it happens on a button action
- (IBAction)changeOrientationButtonPressed:(UIButton *)sender
{
isInLandsCapeOrientation = true;
UIViewController *viewController = [[UIViewController alloc] init];
[self presentModalViewController:viewController animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
This works fine for me.
To change Orientation portraid mode to landscap mode use this code
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
use this code for programmatically change orientation...
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
If you want to change the particular view only in landscape..then u can try the following in its viewDidLoad
float angle = M_PI / 2;
CGAffineTransform transform = CGAffineTransformMakeRotation(angle);
[ [self.view] setTransform:transform];
The documentation describes the orientation property as being read-only, so if it works, I'm not sure you can rely on it working in the future (unless Apple does the smart thing and changes this; forcing orientation changes, regardless of how the user is currently holding their device, is such an obvious functional need).
As an alternative, the following code inserted in viewDidLoad will successfully (and somewhat curiously) force orientation (assuming you've already modified you shouldAutorotateToInterfaceOrientation ):
if (UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation]))
{
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
}
Clearly, this does it if the user is currently holding their device in portrait orientation (and thus presumably your shouldAutorotateToInterfaceOrientation is set up for landscape only and this routine will shift it to landscape if the user's holding their device in portrait mode). You'd simply swap the UIDeviceOrientationIsPortrait with UIDeviceOrientationIsLandscape if your shouldAutorotateToInterfaceOirentation is set up for portrait only.
For some reason, removing the view from the main window and then re-adding it forces it to query shouldAutorotateToInterfaceOrientation and set the orientation correctly. Given that this isn't an Apple approved approach, maybe one should refrain from using it, but it works for me. Your mileage may vary. But this also refers to other techniques, too. Check
SO discussion
I'm trying to hide an image in a view controller when the device is rotated. I'm posting a notification in PlayerViewController and am listening for it in the app delegate, which is responsible for the bannerView:
- (void)orientationChanged:(NSNotification *)notification {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if ((orientation == UIDeviceOrientationLandscapeLeft) ||
(orientation == UIDeviceOrientationLandscapeRight)) {
bannerView.hidden = ([[self.navigationController visibleViewController] isKindOfClass:[PlayerViewController class]]) ? YES : NO;
} else {
bannerView.hidden = NO;
}
}
The PlayerViewController sends a notification and the app delegate hides the bannerView. However, when the device is laid flat on a table, the image shows. Works fine when the device is held vertically but horizontally the image appears... odd.
Here is the code to send the notification:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
... hide other stuff in this view controller
}
Any ideas why this odd behavior is occurring?
Just one tidbit more information. In the simulator the image shows when the device is in upside-down orientation, even though I have:
- (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIDeviceOrientationPortrait) {
return YES;
} else {
return NO;
}
}
Your error might be happening because of when you're posting the notification.
willAnimateRotationToInterfaceOrientation is called before the orientation change takes place (hence the "will" in the method name). So if we're going from portrait to landscape, the current orientation may still be reported as portrait (it may not, it depends).
Now, the willAnimate... call returns the toInterfaceOrientation - the orientation that is going to happen.
You trigger your notification when you receive the willAnimate... call, and inside that notification call [[UIDevice currentDevice]orientation]: which will return portrait. Instead of requesting the orientation in your notification method you should instead pass the orientation provided in the willAnimate call.
If that wasn't clear, the one sentence summary: willAnimateRotationToInterfaceOrientation is called before the rotation changes.
I was curious to know if there is some way to determine the orientation of a screen on iPhone/iPad.
Currently I find myself setting a member variable when this message is called:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
self.orientation = interfaceOrientation;
return YES;
}
... which feels like something I should be able to query as a state instead of having to track it when it changes.
UIViewController has the interfaceOrientation property.
Don't get confused by orientation in UIDevice, which is not the orientation of the interface, but the physical orientation.
Use this if you have a status bar on top.
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
// portrait
} else {
// landscape
}
You can do [[UIDevice currentDevice] orientation].