In my iOS app, the interface is created by programmatically adding multiple UIViews to the UIViewController that is currently on the screen. Currently the app works in the portrait orientation, but I want to add the ability to work in landscape. I want to change the interface when the app is put in the landscape orientation. Hoe can I do this?
P.S. I can't use the interface builder
You need to watch for the orientation to change via the NSNotificationCenter then handle it.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
Then create the method to handle the rotation
- (void)orientationChanged:(NSNotification *)notification
{
// Get device orientation
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsPortrait(deviceOrientation))
{
// Portrait
}
else if(UIDeviceOrientationIsLandscape(deviceOrientation))
{
// Landscape
}
}
Related
I have been working an iOS 7 app to make it compatible for ios 8 (beta 5). In this application, UIViewController (vc1) presents another UIViewController (vc2). vc1 supports both Portrait and Landscape orientations; vc2 supports only Portrait orientation. When vc2 is presented, it asks vc1: shouldAutorotateToInterfaceOrientation: and this returns YES.
In iOS8 (Beta 5) willRotateToInterfaceOrientation: and didRotateFromInterfaceOrientation: are not getting called as well as the new iOS 8 API method viewWillTransitionToSize. But, this works fine in iOS7.
I know willAnimateRotationToInterfaceOrientation and didRotateFromInterfaceOrientation are deprecated in iOS 8, but even iOS 8 delegate methods are not getting called. Every time when launched vc2 from vc1 always screens loads in portrait mode only even though I mentioned supported interface orientation as landscape left.
Any ideas... is it a bug in iOS8?
Well, I didn't figure out your problem best but as soon I have a bunch of lines working fine with rotation in iOS 8.1 I will present them to you. They are just taken and a little bit of edited from the Apple API Reference.
Simply I put this in every VC and i just edit the code when needed. For example I have an app that have initial view controller in portrait and then VC changes ( segue is done ) to a LandscapeVC with different features.
This is the portrait view methods leading to a rotation in LandscapeView.
bool isShowingLandscapeView = false;
- (void)awakeFromNib
{
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
isShowingLandscapeView = YES;
[self performSegueWithIdentifier:#"toLandscape" sender:self];
}
I hope I made it simple for understanding. Don't hesitate to improve my answer, we all learn in this life !
I am developed an application which supports both Portrait and Landscape orientation with the GPOrientationKit. I followed following link to do all the pages of the app to support both the orientations.
http://logisian.blogspot.in/
I did that app with XIB or NIB file. Now, I am currently working on an app with the storyboard. I don't know how to do the app which support both the orientations with the storyboard. GPOrientationKit worked well for XIB files. But I am struggling with storyboard.I need the functionality like GPOrientationKit with the storyboard. Please help me to do that.
Thanks in Advance.
Just add two subview to your mainView of your controller such as portraitView and landscape View, and toggle between those to as and when your orientation changes..I had something like this
In your viewWillAppear method add this
-(void)viewDidAppear:(BOOL)animated{
if(UIDeviceOrientationIsPortrait(self.interfaceOrientation))
{
//Keep LAndscape View Hidden
self.portraitVIew.frame=self.view.frame;
[self.view addSubview:self.portraitVIew];
}else{
//Keep portrait View Hidden
self.landscapeView.frame=self.view.frame;
[self.view addSubview:self.landscapeView];
}
self.view.autoresizesSubviews = YES;
}
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(deviceOrientationDidChangeNotification:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
and then implement the method deviceOrientationDidChangeNotification such as
- (void)deviceOrientationDidChangeNotification:(NSNotification*)note
{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if(UIDeviceOrientationIsLandscape(self.interfaceOrientation))
{
//Keep portrait View Hidden
NSLog(#"YUP THIS IS LANDSCAPE");
self.landscapeView.hidden=NO;
self.landscapeView.frame=self.view.frame;
[self.portraitVIew removeFromSuperview];
///self.landscapeView.frame=CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:self.landscapeView];
}else {
//Keep LAndscape View Hidden
self.landscapeView.hidden=YES;
self.portraitVIew.frame=self.view.frame;
NSLog(#"Portrait");
[self.view addSubview:self.portraitVIew];
}
}
you click to project>select target > General you set the device Orientation.
I have been looking into ways of setting up separate landscape and portrait view controllers to handle a changing orientation. The code posted below is from Apple stating how to do this. I noticed they use performSegueWithIdentifier. It seems odd that a segue is being used.
In order to create a segue on the storyboard I'm assuming I must create a hidden button and drag the connection from the portrait to the landscape view controller. I can then set the segue identifier to "DisplayAlternateView". What is the default segue animation? Or is the default to turn the animation off?
Also why is this code in the awakeFromNib method? Shouldn't it be in viewDidLoad? Is awakeFromNib called before viewDidLoad?
Also I'm assuming I must have a different target action for every scene of my storyboard. If I have portrait view A, B and C with a corresponding landscape view A, B and C, should I have the following changes to the Apple code
on my A view:
selector:#selector(orientationChangedA:)
then on my B
selector:#selector(orientationChangedB:)
then on my C
selector:#selector(orientationChangedC:)
This way each method can perform it's own segue.
I feel like I might be over complicating things here. Are the separate segues causing me to do extra work or is this how how orientation switching to separate view controllers normally handled?
Here is the code from Apple saying how to handle orientation changes with different view controllers:
#implementation PortraitViewController
- (void)awakeFromNib
{
isShowingLandscapeView = NO;
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation) &&
!isShowingLandscapeView)
{
[self performSegueWithIdentifier:#"DisplayAlternateView" sender:self];
isShowingLandscapeView = YES;
}
else if (UIDeviceOrientationIsPortrait(deviceOrientation) &&
isShowingLandscapeView)
{
[self dismissViewControllerAnimated:YES completion:nil];
isShowingLandscapeView = NO;
}
}
Excuse my English.. :)
In my viewController (A) there is a orientation notifier like this:
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{ UIDeviceOrientation newOrientation = [[UIDevice currentDevice] orientation];
if (newOrientation == UIDeviceOrientationUnknown || newOrientation == UIDeviceOrientationFaceUp || newOrientation == UIDeviceOrientationFaceDown) {
UIInterfaceOrientation mainOrientation = [[UIApplication sharedApplication] statusBarOrientation];
newOrientation = (UIDeviceOrientation) mainOrientation;
}
This is working properly when this is the controller.
There is a ModalViewController (B) that sometimes appear, and this could be reoriented to new orientation, and do it perfect. BUT, when this modal is dismissed, the main view controller remains in the same orientation it was before.
Controlling by breakpoints I´ve checked that the code in the method above is not being executed.
All this has been working perfectly before I actualized IOS5 SDK.
(I´ve not refactoriced to ARC, because of CGPLOT issues).
Any one could help me, or has suffered same issue?
The obvious solution is to call this method from the modal view... but it´s annoying..:(
Thanks you very much and have a nice day!
Send a notification using
[[NSNotificationCenter defaultCenter] postNotificationName:#"changeOrientation" object:nil];
from view where didRotate... worked and in other class use:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doWork) name:#"changeOrientation" object:nil];
to catch this event.
Лайтбрингер с ЕГ-форума?
This requirement is for iPad.
I have an UIView which used as Camera overlay view when launching video recording. It set in UIImagePickerController as below.
[self presentModalViewController:pickerController animated:NO];
pickerController.cameraOverlayView =myOwnOverlay;
This is my requirement that i have to provide my own overlay in UIImagePickerController when calling camera for video recording.
I want to lock my own camera overlay UIView into LANDSCAPE mode only, so that allow user can record video in Landscape mode only and not in Portrait mode, this is also my project requirement.
I know about shouldAutorotateToInterfaceOrientation which is used for UIViewController. I used "[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];" it, it locks to Landscape mode when i launch this camera own overlay UIView, but when i rotate the device, UIView also rotates to Portrait. I don't want Portrait mode at all. I tried to handle this issue like below, but its not working for UIView. Then i saw this is possible in UIviewController, but not in UIView. But i must to have UIView for this camera launch operation.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation==UIInterfaceOrientationLandscapeRight || interfaceOrientation==UIInterfaceOrientationLandscapeLeft);
}
Please suggest me how can i provide solution for orientation lock for my UIView?
Thank you!
Doubt over allowing from APPLE but If you want the UIImagePickerController to start(and stay) in Landscape orientation use following code.
//Initialize picker
UIImagePickerController * picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
//set Device to Landscape. This will give you a warning. I ignored it.
//warning: 'UIDevice' may not respond to '-setOrientation:'
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
//Set Notifications so that when user rotates phone, the orientation is reset to landscape.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
//Refer to the method didRotate:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didRotate:)
name:#"UIDeviceOrientationDidChangeNotification" object:nil];
//Set the picker source as the camera
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
//Bring in the picker view
[self presentModalViewController:picker animated:YES];
The method didRotate:
- (void) didRotate:(NSNotification *)notification
{
//Maintain the camera in Landscape orientation
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
}
Credit for This code belongs to UIImagePickerController in Landscape
Try this:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
BOOL isLandscapeRight = (UIInterfaceOrientationLandscapeRight == interfaceOrientation);
return isLandscapeRight;
}
And Also Have to set Your Applications info.plist's interface orientation to Landscape (right home button)
There is a simple solution to this
In the info.plist file edit the entry supported interface orientation ipad.