I have a problem in programming. I have two view controllers. The first runs only in landscape left / right, the other runs only in portrait. If I switching between the views the orientation do not change automaticly. Only when I turn the device the orientation is changing. After that the orientation is fixed. Is it possible to change the orientation automaticly when I switching between the controllers?
As Example when I press the BackButton in the Landscape View Controller and it switch to the Portrait View Controller that the orientation automaticly switch from Landscape to Portrait?
Sorry for my bad english, it is not my native language.
Thanks,
Tim
Try the following Code for Portrait in Second View.
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
}
Try the following Code for Landscape in First View.
- (void)viewWillAppear:(BOOL)animated {
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscape];
}
if(UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation))
{
self.view.frame = CGRectMake(0,0,1024,768);
}
else
{
self.view.frame = CGRectMake(0,0,768,1024);
}
----use this code where you want to change---
Related
I have one app always presenting in Portrait mode (in the summary of the Xcode project, only the portrait orientation is supported).
Now what I want to do is when I'm using the app, from any view controllers of the app, if I rotate the device in landscape right, the app presents a view controller (ARViewController.m) in landscape right, in fact the rotation to landscape right is the trigger to present ARViewController.m. But what I've experienced is, since the the first view controller only supports portrait and even if I orient the device in landscape right, the view controller (ARViewController.m) I want to present from the first one is in portrait too, not in landscape right.
Even if I write this in the second view controller (ARViewController.m), it doesn't autorotate (this view controller can be presented in every orientations):
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return YES;
}
I have to rotate the iphone once after the second view controller (ARViewController.m) is presented to have all in order.
And here is how I call this second view controller (ARViewController.m) from the first view controller:
ARViewController *arVC = [[ARViewController alloc] initWithNibName:#"ARViewController" bundle:nil];
[self presentModalViewController:arVC animated:YES];
I'm calling it from "ViewController.m", this one is defined as the rootViewController in the AppDelegate.m.
This is the first time I'm doing such things, I've looked for solutions but still the same problem. Any tips on this?
I finally solved this problem, I suppose there are alternatives but this one works fine:
In fact I kept only Portrait in the orientation restrictions. Then when I turn the phone in landscape right or left, I call my ARViewController modally, but before loading it I force this view controller to landscape (in viewWillAppear) by making an appropriate rotation like here:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self transformView2ToLandscape];}
-(void) transformView2ToLandscape {
NSInteger rotationDirection;
UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
if(currentOrientation == UIDeviceOrientationLandscapeLeft){
rotationDirection = 1;
}else {
rotationDirection = -1;
}
CGAffineTransform transform = [arController.viewController.view transform];
transform = CGAffineTransformRotate(transform, degreesToRadians(rotationDirection * 90));
[arController.viewController.view setTransform: transform];}
Edit: In Swift 4
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
transformViewToLansdcape()
}
func transformViewToLansdcape(){
var rotationDir : Int
if(UIDeviceOrientationIsLandscape(UIDevice.current.orientation)){
rotationDir = 1
}else{
rotationDir = -1
}
var transform = self.view.transform
//90 for landscapeLeft and 270 for landscapeRight
transform = transform.rotated(by: (rotationDir*270).degreesToRadians)
self.view.transform = transform
}
extension BinaryInteger {
var degreesToRadians: CGFloat {
return CGFloat(Int(self)) * .pi / 180
}
}
What i've found is that first of all, what's stopping the entire application from rotating is the project summary sheet. What you should do is deselect the restrictions in the project summary sheet & just put a method in each UIViewController like you'd like it to be. In the UIViewController that you have, make the method available for the landscape orientations & implement the method
[UIViewControllerSubclass willRotateToInterfaceOrientation:<interfaceOrientation> duration:<NSTimeInterval>]
what Apple says:
willRotateToInterfaceOrientation:duration:
Sent to the view controller just before the user interface begins rotating.
(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
Parameters
toInterfaceOrientation
The new orientation for the user interface. The possible values are described in
UIInterfaceOrientation.
duration
The duration of the pending rotation, measured in seconds.
Discussion
Subclasses may override this method to perform additional actions immediately prior to the rotation. For example, you might use this method to disable view interactions, stop media playback, or temporarily turn off expensive drawing or live updates. You might also use it to swap the current view for one that reflects the new interface orientation. When this method is called, the interfaceOrientation property still contains the view’s original orientation.
This method is called regardless of whether your code performs one-step or two-step rotations.
so, this seems like the method you are looking for. Just implement this, and put your view calling code inside & it should work. (also, put one of these in the presented view to return when rotated back)
also, you should consider not presenting the view controller modally as it is rotating anyways and is obvious that the display is changing.
I have two views in my App and i am having problem loading my second view when i rotate my emulator.
My first view redirects my app to second view on a button event.
When i try to rotate each view independently, it works perfect. But if i load my first view and rotate the emulator then try to load another view i am getting this :-
second view loaded as portrait where my emulator's orientation is landscape.
But if i load my second view before rotating the emulator and then rotate it, it gets loaded perfect.
Do i need to resize my view or need to call any function to make it load properly?
i am a newbie in iOS world so any help would be highly appreciated.
Thanks.
Make sure that in your second view you use this method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
Add new view to UINavigationController using following code:
- (IBAction)changeView:(id)sender
{
RedClass *redClass = [[RedClass alloc] initWithNibName:#"RedClass" bundle:nil];
[self.navigationController pushViewController:redClass animated:YES];
[redClass release];
}
If you cal that method then your view will autoresize.
When you just adding to subview using method self.view addSubview:redClass.view]; it will autoresize if only current view will be changed after adding.
I have a tab based application with 4 views associated with 4 tabs. I want all 3 views in portrait form and only one landscape form.
I have done these settings for that particular view:
Set the required value in Supported interface orientations of info.plist.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight)
}
In IB set the orientation attribute as landscape.
In -(void)viewDidLoad I have set self.view.frame=CGRectMake(0, 0, 480, 320);
After done all above setting, its still not coming in landscape mode.
If I understand your question correctly, and please correct me if I do not, then you want to have 3 views in portrait all of the time and one view in landscape all of the time. To accomplish this, set the orientation of the status bar for each viewController in viewWillAppear:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
}
I have a tab bar application in which i have 3 diffrent views each with there own view controller.
In the tab bar code i have this, to handle rotation.
#import "RotatingTabBarController.h"
#implementation RotatingTabBarController
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
#end
Then in the 2nd view controller that i want to rotate depending on device orientation i have:
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
And For the other two views that i do not want to rotate i have this method set.
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
The PROBLEM: so this works fine in view 1 and view 3 when u rotate the device they stay in portrait mode which is desired. When in view 2 i rotate to landscape, the view does as expected and rotates to landscape. BUT when click view 1 or view 3 tab while in lanscape mode in view 2, View 1 and View 3 are in landscape mode.
I can't figure out how to force them in portrait even if view 2 rotates to lanscape.
Any one know how to do this?
There's a big discussion[1] on this dating back from 2008 until now (look at comments down a few pages) -- summarily it seems like
application.statusBarOrientation = UIInterfaceOrientationLandscapeRight;
or
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
or
[application setStatusBarOrientation: UIInterfaceOrientationLandscapeRight animated:NO];
will let you force it to landscape -- you would want to do this when the user goes back to your landscapey view(s) programmatically.
[1] iPhone app in landscape mode, 2008 systems
I use a tabBar Controller as root controller. It has 4 tabs and each of its ViewControllers has
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
as well as the tabBarController itself.
But when I rotate the device (real or simulator), the screen turns at random! If it doesn't turn when I open the application it would have the same behavior until I quit the app.
I tried to add the 4 viewControllers one by one in IB to see if one was problematic, but I obtained the same issue. It only always turns when there is no tabs at all!
Please tell me if you have any ideas. Thanks!
You set every view controller to say that it responds to any possible orientation. Therefore, every view will attempt to rotate to every orientation.
Views don't really automatically rotate. You usually have to manage the placement of subview programmatically in all but the simplest views.
If you have no custom orientation code, you're probably seeing the views try to draw the portrait view in the landscape frame or vice versa. If you have autoresize subviews set your subviews will appear to scatter across the screen in a seemingly random pattern. The more you change orientation, the more random the placement becomes.
For complex views, I like to create separate viewController/view pairs for each orientation. Then I put the views in a nav controller. As the orientation changes, each view controller will push or pop the appropriate view controller for the coming orientation onto/off the stack. To the user, this looks like a single view is gracefully redrawing itself. (This is especially useful if you have non-standard UI elements that have to be manually rotated with transforms)
You have to subclass UITabBarController and implement shouldAutorotateToInterfaceOrientation:
Actually, I just want my first tab view controller to rotate. So I put this code in my custom tabBarController :
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
if (self.selectedIndex == 0) {
return toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown;
}else {
return toInterfaceOrientation == UIInterfaceOrientationPortrait;
}
}
but I had the same problem. I use a custom orientation code for my first tab view controller when turning to landscape. Called with the following function in my custom tabBarcontroller:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
//rotation to Portrait
lastOrientation = toInterfaceOrientation;
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
[self.selectedViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
else if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
if (!UIInterfaceOrientationIsLandscape(lastOrientation)) {
//rotation to Landscape
[self.selectedViewController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
lastOrientation = toInterfaceOrientation;
}
}
I found that if you set the selected tab programmatically the tabViewController rotates erratically.