I have two view controllers, in which I am using navigation controller to navigate from one view to another.....
In my first view controller I'm checking the orientation in this way in my - (void)viewDidLoad
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
//Do this task
}
else
{
//Do this task
}
When I was trying to navigate from second to first viewcontroller..
I am using this code to navigate
-(IBAction)back
{
[self.navigationController popViewControllerAnimated:YES];
}
Here the problem arises...
The above orientation condition is not checked.. When I was trying to navigate from second to first view controller......
I don't know where I was lagging.... Whether I was stuck up with any logics or I want to change my code???????
call this method
-(void) viewWillAppear:(BOOL)animated{
[self willAnimateRotationToInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation duration:0];
}
-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown )
{
set frame here........
}
else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight )
{
set frame here........
}
}
Related
The root view controller of navigation controller supports only portrait orientation and other controllers supports all orientation.Now if i am on the root view controller and the DEVICES is in landscape and if i push next view controller that opens in portrait that should open in landscape as it supports all orientation.
Please help me with this.
Using iPhone 4s iOS6.1.3
you can check Device orientation in your first screen after login viewcontroller using bellow code:-
-(void)viewWillAppear:(BOOL)animated
{
[self willRotateToOrientation:[[UIDevice currentDevice] orientation]];
[super viewWillAppear:YES];
}
- (void)willRotateToOrientation:(UIInterfaceOrientation)newOrientation {
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
if (newOrientation == UIInterfaceOrientationLandscapeLeft || newOrientation == UIInterfaceOrientationLandscapeRight) {
//set your landscap View Frame
[self supportedInterfaceOrientations];
}
}
else if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
{
if(newOrientation == UIInterfaceOrientationPortrait || newOrientation == UIInterfaceOrientationPortraitUpsideDown){
//set your Potrait View Frame
[self supportedInterfaceOrientations];
}
}
// Handle rotation
}
sor when you load this viewcontroller it check first device oriantation and then load it's related frame
I think this is the issue related to the orientation changes in iOS6. You need to subclass the UINavigationController
Check this
1 . You have to create sub class of UINavigationController. add Following method.. Take one boolean variable to check whether it support for all orientation or not and change its value.
#implementation NavigationControllerViewController
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
AppDelegate *appdelgate=[[UIApplication sharedApplication]delegate];
if (appdelgate.issuppoertAll) {
// for iPhone, you could also return UIInterfaceOrientationMaskAllButUpsideDown
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
#end
2 when you navigate form root view controller to other view controller
use this code , when you want to forcefully change its orientation.i.e lanscape to portrait
obj_viewcontroller = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self presentModalViewController:obj_viewcontroller animated:NO];
[self dismissModalViewControllerAnimated:NO];
[self.navigationController pushViewController:obj_viewcontroller animated:NO];
3 In second view controller you have to change boolean variable value
-(void)viewWillAppear:(BOOL)animated
{
appdelgate.issuppoertAll=YES;
}
4 Add this method into all view controller and set orientation as per your need.
- (NSInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
So I have a view that I present modally when the interface orientation changes to landscape. However when the orientation returns to portrait and the modal view dismisses itself, the tableview from the initial view remains in landscape orientation (this table view must be only in portrait orientation)
Here is the code :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return ((interfaceOrientation == UIInterfaceOrientationPortrait) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight) );
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) {
[self performSegueWithIdentifier:#"showCatChart" sender:self];
}
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self refreshTableView];
}
}
I tried to refresh the tableview but that doesn't make it portrait again ...
this could be from the view hierachy ...
NavigationController->tableView (only portrait)->tableview->landscapeViewModalController
With iOS 6, you need to implement the following:
- (BOOL)shouldAutoRotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
In your AppDelegate, you need to change the following:
[self.window addSubview:viewController.view];
to
[self.window setRootViewController:viewController];
Also, keep your current code if you want to support previous versions of iOS.
Use the following in appdelegate.
[self.window addsubview:viewcontroller];
This alone will solve your orientation problem.
I am making app like whenever the device change it's orientation mode it changes it's view.
At first when the view is portrait it shows perfect SearchViewController, then when i rotate to landscape it push to new view MapView in landscape ... now when i again change the view to portrait the map rotate to portrait... but it should be do to search view controller... and one more thing when i tapped detail disclosure button it should be go to back to search view controller... i think navigation controller not work in map view..
this is my code part of searchViewController
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//return (interfaceOrientation == UIInterfaceOrientationPortrait);
if(interfaceOrientation == UIInterfaceOrientationPortrait|| inte rfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
}
else {
MapView *mapView = [[MapView alloc] initWithNibName:#"MapView" bundle:nil];
mapView.title = #"Map";
[self.navigationController pushViewController:mapView animated:YES];
return YES;
}
return YES;
}
and this is my MapView code
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
// return (interfaceOrientation == UIInterfaceOrientationLandscapeRight|| UIInterfaceOrientationLandscapeLeft);
if(interfaceOrientation == UIInterfaceOrientationPortrait|| interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
NSLog(#"hi Potrait");
[self.navigationController popViewControllerAnimated:NO];
return YES;
}
else {
}
return YES;
}
shouldAutorotateToInterfaceOrientation: is an incorrect place to implement any kind of navigation. You should do it in didRotateFromInterfaceOrientation: instead. Check the current interfaceOrientation and push or pop if necessary.
In searchViewController,
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if ( UIInterfaceOrientationIsLandscape(self.interfaceOrientation) ) {
MapView *mapView = [[MapView alloc] initWithNibName:#"MapView" bundle:nil];
mapView.title = #"Map";
[self.navigationController pushViewController:mapView animated:YES];
}
}
In MapView,
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if ( UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ) {
[self.navigationController popViewControllerAnimated:NO];
}
}
And alter your shouldAutorotateToInterfaceOrientation: to
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
View Controller A displays View Controller B in horizontal orientation
#pragma mark Rotation Delegate Methods
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return YES;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
[landscapeChartViewController.chartImageView reloadWithUrl:
[NSString stringWithFormat:#"someurl",[symbol uppercaseString]]];
NSLog(#"showing chart");
[self presentModalViewController:landscapeChartViewController animated:NO];
}
}
This works fine. View Controller B shows up in landscape orientation. Here is View Controller B's implementation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(#"dismissing chart");
[self.parentViewController dismissModalViewControllerAnimated:NO];
}
}
The problem is, when I go back into portrait orientation to show View Controller A, View Controller A is stuck in landscape orientation. How can I fix this?
EDIT: after reading your comment, I suggest trying to use willRotateToInterfaceOrientation:duration: instead of willAnimateRotationToInterfaceOrientation, like this:
controller A:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
[landscapeChartViewController.chartImageView reloadWithUrl:
[NSString stringWithFormat:#"someurl",[symbol uppercaseString]]];
NSLog(#"showing chart");
[self presentModalViewController:landscapeChartViewController animated:NO];
}
}
controller B:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(#"dismissing chart");
[self.parentViewController dismissModalViewControllerAnimated:NO];
}
}
I do more or less the same in a project of mine, only between two non modal views.
One option is to move your code from willAnimateRotationToInterfaceOrientation: to didRotateFromInterfaceOrientation: and use self.interfaceOrientation in place of toInterfaceOrientation.
View Controller B shows up in landscape orientation. Here is View Controller B's implementation:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(#"dismissing chart");
[self dismissModalViewControllerAnimated:NO];
}
}
Did you implement the function willRotateToInterfaceOrientation? Also try using the Notification centre to notify the parent view controller that your modal view controller is rotated and then simply [self dismissModalViewControllerAnimated:YES]
I always write my orientation logic in didRotateFromInterfaceOrientation.
Here is a part of my code it works fine....
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[connectCoverLockUnlockSwitch setFrame:CGRectMake(250,6,51,31)];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight){
[connectCoverLockUnlockSwitch setFrame:CGRectMake(400,6,51,31)];
[self.tableView reloadData];
}
else if (orientation == UIDeviceOrientationPortraitUpsideDown || orientation == UIDeviceOrientationPortrait){
[connectCoverLockUnlockSwitch setFrame:CGRectMake(250,6,51,31)];
}
}
else if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationUnknown || orientation == UIDeviceOrientationFaceUp) {
//return;
}
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {
[connectCoverLockUnlockSwitch setFrame:CGRectMake(570,6,51,31)];
[self.tableView reloadData];
}
else if (orientation == UIDeviceOrientationPortraitUpsideDown || orientation == UIDeviceOrientationPortrait)
{
[connectCoverLockUnlockSwitch setFrame:CGRectMake(330,6,51,31)];
[self.tableView reloadData];
}
}
So I have a UITableViewControler displaying a tableview in portrait mode.
As soon as i rotate the iPhone i want to present a modal view in landscape mode.
In the tableView i use:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
And to handle the present the modal view:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration {
if((interfaceOrientation == UIInterfaceOrientationLandscapeRight) || (interfaceOrientation == UIInterfaceOrientationLandscapeLeft))
{
NSLog(#"Push page view");
PagingViewController *s = [[PagingViewController alloc] initWithNibName:#"PagingView" bundle:nil];
s.hidesBottomBarWhenPushed = YES;
[self presentModalViewController:s animated:YES];
[s release];
}
}
The modal view i have the following:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
And to dismiss the modal view it self, I do:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration {
if (interfaceOrientation == UIInterfaceOrientationPortrait)
{
NSLog(#"Dismiss my self");
[self.parentViewController dismissModalViewControllerAnimated:YES];
}
}
Some how this works two times.
The third time i rotate the iPhone from Portrait mode to Landscape mode, i get a bad access error.
I cant figure out what gives me the error.
Anyone care for a shot?
The simplest way I can think of is to implement -shouldAutorotate... and dismiss the modal view and return NO to abort rotation. Perhaps that will be sufficient to avoid any concurrency issues. If this suggestion isn't to your liking take a look at NSNotificationCenter.