I have a Table View Controller (root) and 5 View Controllers in my project. The view Controllers turn only to landscape view (as I want) but not the Table View Controller (only in the Portrait view).In supported Device Orientations I deleted Portrait and Upside down, and I wrote in every class:
(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
Any suggestions to make Table view turn only to landscape view?
put this in the viewDidLoad
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Related
I have one application in which a tab bar controller is having 3 tabs and each tab having a view controller.
View controller 1 and 2 are supporting only portrait mode but view controller in tab 3 supports all orientations -portrait, landscape left, landscape right and portrait upside down.
For tab 3, We have to show a particular view when device is in portrait mode and another view when device is in landscape mode.
If device is in portrait mode and user clicks on the tab 3, view is loaded correctly in portrait mode and then if we rotate the device to landscape mode the landscape view is loaded correctly.
But it we turn the device to landscape mode in the tab 1 itself and then click on the tab 3 , then the problem occurs then it shows the screen to be shown in landscape mode but it displays it as a portrait view.
When I tried to find out the reason for this in the delegate method by NSLogging
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
the value of the interfaceOrientation is 1 which is UIInterfaceOrientationPortrait
and the control is going into the if condition written for the portrait mode
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
and when I tried to print the value of UIDevice orientation in the same delegate method
UIDeviceOrientation interfaceOrientation = [UIDevice currentDevice].orientation;
NSLog(#" device orientation %u", interfaceOrientation);
the value printed in console is 4- which is UIDeviceOrientationLandscapeRight.
So the interface orientation is UIInterfaceOrientationPortrait but device orientation is UIDeviceOrientationLandscapeRight.
One more thing, now if I rotate the device to portrait mode and then moving to landscape mode shows the correct landscape view and app starts behaving correctly.
So the problem is if I load the tab 3 in landscape mode it doesn't load properly
but if we enter in portrait mode and then rotate to landscape if works fine from thereon.
If anyone can give some useful suggestion why the behavior is like this that would be really beneficial.
Thanks
Add these lines to your Tab1 & Tab2 in viewWillAppear method,
#import <objc/message.h>
- (void)viewWillAppear:(BOOL)animated {
if(UIDeviceOrientationIsLandscape(self.interfaceOrientation)){
if ([[UIDevice currentDevice] respondsToSelector:#selector(setOrientation:)]) {
objc_msgSend([UIDevice currentDevice], #selector(setOrientation:), UIInterfaceOrientationPortrait );
}
}
}
Create a CustomTabBarController Class with Subclass of UITabBarController (for e.g: CustomTabBarController)
#interface CustomTabBarController : UITabBarController
Add the following lines to this class :
- (BOOL)shouldAutorotate
{
return [self.selectedViewController shouldAutorotate];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [self.selectedViewController supportedInterfaceOrientations];
}
In your app delegate or where ever you are initializing UITabBarController, replace those instances with CustomTabBarController instances.
self.tabBarController = [[[CustomTabBarController alloc] init] autorelease];
Add the lines to your model view controllers with different view controller support:
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate {
return NO;
}
I have two view controller in my app.
1st view controller is portrait mode and 2nd view controller in landscape mode.
I don't want to change their orientation even when i rotate my iPhone.
How can i make?
In the Xcode, highlight the project in the Project Navigator, and select the target in the project tree. Open the Summary page, and go to the Supported Interface Orientations section. Un-click the orientations that you do not want your application to support.
In the story board, choose your first view controller, go to the Attributes inspector, and set orientation to "Portrait" in the Simulated Metrics section. Now choose the second view controller, and set its orientation to "landscape".
In the view controller code, implement
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
for the first view controller, and
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
for the second view controller. This should fix the problem for you.
In your case you have two VCs. So in both VC under below method just handle you orientations. and perform check against toInterfaceOrientation and return YES.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
// For your VC1
if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
return YES;
// For your VC2
/*
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
return YES;
*/
}
I have a view controller in my app. Let its first view controller, my first view controller appears in portrait mode in phone, when user rotate phone in landscape mode, first view controller also rotate in landscape mode.
Its working fine, and now I have a button on first view controller, when I touch the button second view controller appears. I just want to do is that the second view controller should always appear in portrait mode, even though the first view controller is in landscape mode.
Is there any methods which I have to override to get this functionality?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
In second view controller keep this.
In a navigation controller, the orientation of your controller depend on the orientation of the navigation controllerĀ“s root controller.
You have two possibilities:
make your root controller's shouldAutorotateToInterfaceOrientation: return different values depending on which controller is actually shown;
use a transform on you your view controller's view so that it is rotated.
I would give a try to the first way, to start. Have a look at this post for an idea how to do it (just ignore the UITabBarController stuff), or try this (which simply relays the message to the top controller in your navigation hierarchy):
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return [self.navigationController.topController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
In order to achieve the same result on iOS6, try and define the following methods:
-(NSUInteger)supportedInterfaceOrientations {
return [self.navigationController.topController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.navigationController.topController preferredInterfaceOrientationForPresentation];
}
I have used UIDeviceOrientationDidChangeNotification to get notified of landscape and potrait mode. In my project I'm required to change the positions of UIControls placed on the UIView accordingly. Do I have to change the frame size manually for each UIControl, as this is hectic?
In your view controller you should implement method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
This method should return YES for supported orientations.
If you want your subviews to resize and reposition automatically then you should set appropriate property autoresizingMask of that views. For example:
blackView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
You do need to use the shouldAutorotateToInterfaceOrientation... method but you need to do a little more before it will work properly. First of all, you will need two xib files, one for a landscape orientation and one for a portrait orientation. You will then need to use your function like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft){
//prepare for a Landscape view
}
else{
//prepare for a portrait view
}
return YES;
}
As for preparing for landscape or portrait views, using autoresizing can work but you may need to have totally seperate xibs. I could not find a way to change the xib within the active view controller, so I would suggest making a seperate instance of your view controller. Example:
When you present your first instance of the viewController, present it with the portrait xib. You may also need a boolean to keep track of the current xib. Then have this code implemented:
/*Assuming you are using a viewcontroller called viewController, and you have a boolean called xibPortrait.
You have presented this view controller using the portrait xib.
You also have a landscape xib, Landscape.xib
*/
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ((interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft) && xibPortrait){
xibPortrait = FALSE;
viewController *Land = [[ViewController alloc] initWithNibName:#"Landscape" bundle:nil];
[self presentModalViewController:Land animated:NO];
[Land release];
}
else if(!xibPortrait){
[self.parentViewController dismissModalViewControllerAnimated:NO];
xibPortrait = TRUE;
}
return YES;
}
//This should work but if you can, you should try to use Autoresizing.
EDIT:
I also found this which someone posted on one of my questions. It may help your app work more efficiently than using my method above:
http://aseriesoftubes.com/articles/ipad-development-101-orientation/
I am working on an app (my first one), which is basically a TabBar app.
To be more precise there are:
- a login view controller
- a tab bar controller (when login is done)
- a landscape view controller that is used when the first itel of the TabBar is switch from Portrait to Landscape.
So, when I am in the first tab, I need to be able to move to landscape view to display some other data. In my tab bar controller, I have implemented those methods:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if([self selectedIndex] == 0)
return YES;
return NO;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
// Get AppDelegate
MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
// Remove TabBarView and add graph Landscape View
[self.view removeFromSuperview];
[delegate setSubViewLandscapeViewController];
}
}
In the delegate, I have implemented the setSubViewLandscapeViewController and the setSubViewTabBarController:
- (void)setSubViewTabBarViewController {
[window addSubview:[tabBarController view]];
}
- (void)setSubViewGraphLandscapeViewController {
[window addSubview:[landscapeViewController view]];
}
I want the landscapeViewController to display only in landscape mode, I have then (in my landscapeViewController):
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
NSLog(#"willRotateToInterfaceOrientation");
}
A part of this works fine, I mean the switch from portrait to landscape is ok (when I am in the first tab), the tabbarcontroller is remove from the SuperView and the landscape view is added as a subview instead.
The thing is... I do not know how to switch back to portrait mode (and then load the previous controller, the tabBar one using the setSubViewTabBarViewController of my delegate). It seems none of the willRotateToOrientation, willRotateFromOrientation, .. are triggered when I actually move the device from the landscape view...
In short, when I am in the landscape view I do not know what to do to move back to the tabbar view... I am kind of stuck in the landscape view once I am in this one.
Thanks a lot for your help,
Luc
Look at the pie chart in CPTestApp-iPhone in the examples folder. It handles rotation by implementing -(void)didRotateFromInterfaceOrientation: and resizing the graph after a rotation.
Well, I managed to get a solution for this problem.
In fact, while moving from portrait to landscape I removed the tabbarcontroller from window subview and add the landscapeviewcontroller instead.
It seems it was not the correct thing to do.
Instead, I add the landscapeViewController as subview of the tabbarcontroller and remove it when going from landscape to portrait.
I still have a problem however with the y position of the landscape view which seems to changes when I do several decive rotation in a row....
Regards,
Luc