I have one specific viewcontroller which I wish to behave that way:
When loading, if device is landscaped, show landscape but no auto rotation.
When loading, if device is Portrait, show portrait but no auto rotation.
I cannot find the right solution for that, can any one advise?
Try checking the orietation on viewWillAppear() and then set views to show on the way you want according to the orientetation.
int orientationType = [[UIDevice currentDevice] orientation];
1 = Portrait 2 = Portrait (Upside down) 3 = landscape (Right) 4 = landscape (Left)
To disable auto rotate on a view just:
- (BOOL) shouldAutorotate {
return NO;
}
Related
I have set the NSLayoutConstraint as IBOutlet, and the values I've set in the storyboard and IB is for portrait orientation. When I run the app in portrait orientation and then I rotate the device to landscape, I manage the constraints updates. But when I run the app being the device already in landscape, the constraints have the values for portrait.
Where should I check the current orientation of the device when the view controller is loaded and the view shown, and set the appropriate constraints according to such orientation?
Thanks
you can initially keep a condition in viewDidLoad method
if(UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])){
// Apply Portrait Constraints
}
else{
// Apply Landscape Constraints
}
later when the user changes orientation you can check in below method and apply the same condition
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
// Apply Portrait Constraints
}
else{
// Apply Landscape Constraints
}
}
I have an issue in one of my applications that I just discovered once I got the app onto an actual iPad, it isn't possible to see in the simulator. The issue is when I hold the iPad in landscape orientation, if I tip the iPad back to a certain angle the iPad stays in landscape mode but the view switches to my portraitView while still in landscape mode. In my code I have a function called screenRotated() that is an observer of UIDeviceOrientationDidChangeNotification. My function screenRotated() has the following code:
let interfaceOrientation: UIDeviceOrientation = UIDevice.currentDevice().orientation
if UIDeviceOrientationIsLandscape(interfaceOrientation) {
//does some stuff and then sets self.view = landscapeView
} else {
//does some stuff and then sets self.view = portraitView
}
How do I keep my app from going into the wrong view when in landscape orientation?
You issue will be that you are not handling device orientation notifications for orientations UIDeviceOrientationFaceUp and UIDeviceOrietationFaceDown. These are neither Portrait or Landscape and your code always picks Portrait when the orientation is not Landscape.
Hence as you are tipping back, it goes to orientation face up and your code picks Portrait as it is not landscape but face up.
So add code to detect faceup/down and ideally keep to the orientation last set until you see it actually go from Portrait to Landscape or the other way around.
The following should work:
if UIDeviceOrientationIsLandscape(interfaceOrientation) {
//does some stuff and then sets self.view = landscapeView
} else if UIDeviceOrientationIsPortrait(interfaceOrientation) {
//does some stuff and then sets self.view = portraitView
}
else{
// Do nothing
}
I've been adding support for rotation for an app recently and it has been a pain. One thing I'm finding that's fairly consistently annoying is that one of my views shifts up by about 50 pixels or so everytime I rotate between my landscape and portrait mode.
My landscape mode is not actually the same view controller; I push a viewcontroller when I rotate. However, when I rotate back, I have to reset the portrait's view.bounds or else my view ends up shifting upwards.
So in my rotation code, I have to do this:
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
UIInterfaceOrientation toOrientation = self.interfaceOrientation;
if ( self.tabBarController.view.subviews.count >= 2 )
{
if(toOrientation == UIInterfaceOrientationPortrait)
{
self.tabBarController.tabBar.hidden = NO;
self.navigationController.navigationBar.hidden = NO;
CGFloat height = [[UIScreen mainScreen] bounds].size.height;
CGFloat width = [[UIScreen mainScreen] bounds].size.width;
self.view.bounds = CGRectMake(0, -55, width, height);
}
}
}
Surely this can't be right. In my app, there is a navbar and the standard status bar (batt life, reception, etc) occupying the top of my app. But...it seems like my view is slipping too upwards unless I set the y coordinate origin to be negative (which makes no sense!).
What's happening?
In my app, I hide the tabbar and navbar when I go to landscape mode. The statements to make the bars hidden are written into the portrait view's viewcontroller's code.
When I transition back from landscape mode to portrait mode, the landscape viewcontroller gets popped and I get the weird shifted views. Turns out this was caused by the order in which the tab/nav bar un-hiding statements.
My tab/nav bar un-hiding statements were in the portrait viewcontroller, so they were called too late. After moving the tab/nav un-hiding statements to the rotation code in the landscape viewcontroller (rather than the portrait's viewcontroller), my problem disappeared.
This topic has come up before (iPad modal view controller acting in portrait even though it's landscape) but I haven't found a clear answer - so I don't know if this is a duplicate or not.
In new single view project, I set the main view to landscape in xcode:
And the Property Inspector confirms this (as well as how the view is displayed in the storyboard):
And the ViewController orientation property is set to landscape:
Yet when I check the view frame in 'viewDidLoad' it reports portrait mode:
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect theRect = self.view.frame;
NSLog(#" frame %f %f %f %f", theRect.origin.x,
theRect.origin.y,
theRect.size.width,
theRect.size.height);
}
2012-08-26 16:42:45.045 Test[2320:f803] cell 0.000000 20.000000
768.000000 1004.000000
I also force landscape in shouldAutorotateToInterfaceOrientation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsLandscape(interfaceOrientation);
}
I've encountered this many times before and have had to set the frame explicitly to landscape but I have never understood why all the storyboard settings have no effect.
Am I missing something basic here?
Every application in iOS starts in portrait mode inititally, even if you specified the supported device orientations and give the right "answers" at shouldAutorotateToInterfaceOrientation:. It will always start in portrait and will the rotate to landscape if the device. The user maybe won't see it cause its so fast.
Because of this your app has to be able to rotate via shouldAutorotateToInterfaceOrientation even if your only supported orientations are landscape ones.
So to get a landscape orientation after start you should:
set the supported interface orientations in Xcodes Interface Builder
overide shouldAutorotateToInterfaceOrientation:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)io {
return (io == UIInterfaceOrientationLandscapeRight);
}
give the interface a chance to rotate and do your view configuration afterwards
Regarding your question about the Xcode configuration of the the viewcontroller to landscape: Notice the title of the menu in the storyboard - it says: Simulated Metrics
This means that every modification you do there is just for the purpose to simulate it in the storyboard. But unless you do the necessary modifications to get to this state in the code it will have no effect.
Add below code in your view controller with swift 4.2
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscapeRight
}
I'm wondering why iPad project based on UITabBarController won't autorotate when i specify some of the tab should autorotate in landscape mode and the other will autorotate in landscape and portrait mode.
i've used the
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
for all the UIViewController and specify if landscape return YES; other wise return NO;
In the other hand, if the UIViewController should rotate in landscape and portrait i've justreturn YES;` always.
Thx in advance.
for all the UIViewController you are loading in tabbarcontroller you must return True in
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
Note:
A tab bar controller will not auto rotate unless ALL the controllers it contains also auto rotate.
from Rotate one UIViewController in UITabBar application -->>
There is no easy way to have only one view in landscape mode, while the others are in landscape, nor an easy way to programmatically switch to landscape mode.
One possible approach would be using a CGAffineTransform to transform your view in your viewWillAppear (i.e., right before the view is shown):
- (void)viewWillAppear:(BOOL)animated; {
//-- Adjust the status bar
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
//-- Rotate the view
CGAffineTransform toLandscape = CGAffineTransformMakeRotation(degreesToRadian(90));
toLandscape = CGAffineTransformTranslate(toLandscape, +90.0, +90.0 );
[self.view setTransform:toLandscape];
}