For iOS 10 and below, the following code controlled the orientation of the any respective UIViewController. I have selected Portrait, Landscape Left, and Landscape Right in my Deployment Info, and have the following in my Info.plist:
For my VC's that should not rotate at all I have the following code, which I stated, was working prior iOS 11
- (BOOL)shouldAutorotate {
[super shouldAutorotate];
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
[super supportedInterfaceOrientations];
return UIInterfaceOrientationMaskPortrait;
}
I have tested this on actual devices and as of iOS 11 it does not work.
Even more strangely, logging the registered device orientation as of iOS 11 tells my the device IS portrait... when the controller loads in landscape mode...
Code:
// In viewDidLoad
NSLog(#"orientation: %lu", [[UIDevice currentDevice] orientation]);
Console output:
2017-09-22 15:20:26.225196-0400 <APP_NAME>[2669:1628408] orientation: 1
This occurs either rotating the device left or right before building and running the app.
What is the cause here for this error? If anyone knows please help..
FYI: No, I do not have rotation lock on my device..
Whether this proves to be an iOS 11 bug or not, I seemed to have stumbled upon a "solution" to this issue. For whatever reason, for iOS 11 changing the - (BOOL)shouldAutorotate return to YES allows for the correct orientation...
Objc
- (BOOL)shouldAutorotate {
[super shouldAutorotate];
if (#available(iOS 11, *)) return YES;
return NO;
}
In combination I had to do a manual check for the screen dimensions to see if the width was greater or less than the supposed height of the screen.
width = self.view.frame.size.width, height = self.view.frame.size.height;
if (height < width) width = height, height = self.view.frame.size.width;
Hopefully someone else finds the true cause of this "bug" OR Apple updates their bundle to handle rotations like all previous iOS versions..
Swift 3.2+
override var shouldAutorotate: Bool {
if #available(iOS 11.0, *) {
// Anything else iOS 11 specific
return true
}
return false
}
Related
I've made a puzzle game ('WordBatch', available in the App store) and thought I had forced portrait orientation but its still rotating to landscape mode, though only the iPad. In XCode I specified it as a 'Universal' App, for all devices, and checked portrait mode only in the General tab. Even in the plist file portrait is the only orientation specified. I've tried all the suggestions in StackOverflow on this subject, but to no avail. The current code I have on place is this bit in my AppDelegate:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
and the following is in my root view controller:
-(BOOL)shouldAutorotate {
return NO;
}
but it still rotates to landscape. Any help here would be great.
You can try by applying this check:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// The device is an iPad.
}
else
{
// The device is an iPhone or iPod.
}
I have a structure like this
LoginViewController-->Root
LoginViewController-->UINav---->HomeViewController
Now I have to lock this orientation to portrait only for iPhone and have to provide both orientations for iPad
For the Login Controller, I wrote this
-(BOOL)shouldAutorotate{
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
return YES;
}
else
{
return NO;
}
}
This is working fine. I got only a portrait orientation in iPhone and both portrait as well as landscape orientation in iPad
But the same piece of code is written in HomeViewController is not working.
Is it due to the Navigation Controller which is embedded with HomeViewConroller.
Well. I got a fix for that myself. Posting the solution on what to do as it might help others too.
Just uncheck the Device Orientation checks (LandscapeLeft and LandscapeRight) in Target->General
And write the same piece of code in every controller
-(BOOL)shouldAutorotate{
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
return YES;
}
else
{
return NO;
}
}
This worked for me. Now I only get a portrait mode in iPhone and a landscape as well as a portrait mode in iPad.
With iOS 8.0 in Xcode 6, there is nowhere where I can see that you can specify for each device if you want it portrait or landscape...
I want to have all iPhones only portrait except 6 Plus which should be both portrait and landscape. And I want all iPads to be both portrait and landscape.
Is there a way to do this or even a workaround it?
To make the 6+ different than other iPhones you'll need to implement supportedInterfaceOrientations something like this:
- (NSUInteger)supportedInterfaceOrientations
{
if (iPadOrPhonePlus()) {
return UIInterfaceOrientationMaskAll;
}
return UIInterfaceOrientationMaskPortrait;
}
I haven't settled on a way I like for that helper method but you can start with this:
.#define iPadOrPhonePlus() ((UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) || [[UIScreen mainScreen] scale] > 2)
ignore the . before the #define SO was formatting it strangely without that.
In my app i trying create a Interface builder supports both Landscape and portrait in ipad and iPhone.
[In Android we used fill parent to autoresize dynamically created UI-Elements.is there any syntax in iOS to autoresizing]
How to UI-elements create dynamically supports both Landscape mode and portrait mode?
How create the view controller to support the Landscape mode and portrait mode?
Is there required to create a all views and UI-elements dynamically?
1)If you will make xib or nib than develop xib or nib in only one mode as portrait or landscape. Than use Autoresizing option as below Image for any control.
http://www.raywenderlich.com/50319/beginning-auto-layout-tutorial-in-ios-7-part-2. You can use this link for auto layout.
But Auto layout is not work properly as you want. so u need to set frames of control pro grammatically evenif u r using autolayout.
2) And If you want to develop dynamically than using below code you can set frame of all controls.
In ViewwillAppear.
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil];
in viewdidload
set your controls as below.
UILabel lbl - [UILabel alloc]init];
-(void)orientationChanged{
if(Orientation is portrait){
[lbl setFrame:for portrait];
}else{
[lbl setFrame: for landscape];
}
If device change mode than above notification fire and in that method. you can set frame of control.
I hope you will get your answer.
You can use auto - layout for providing both the portrait and landscape mode.
For more details, check this : What is Auto Layout?.
You have to set the constraints for landscape and portrait mode to work. Like if you want a button at the top, you can set constraints on it : from top and left and so on.
If you want a UI element to work change dynamically, you just need to change frame on orientation as per your requirement. Sample code is here :
# pragma mark - Orientation related methods
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration NS_AVAILABLE_IOS(3_0)
{
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
[self deviceRotatedToLandscapeMode];
}
else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[self deviceRotatedToLandscapeMode];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self deviceRotatedToPortraitMode];
}
else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
[self deviceRotatedToPortraitMode];
}
}
- (void) deviceRotatedToPortraitMode {
self.mTableView.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);
}
- (void) deviceRotatedToLandscapeMode {
self.mTableView.frame = CGRectMake(0.0, 0.0, self.view.frame.size.height, self.view.frame.size.height);
}
The most reliable approach -
Create a method in your view controller -
-(void)setFrameForOrientationChange:(UIDeviceOrientation*) o {
//...
implement your code for frame settings..
}
I am unable to get the UISearchBar to display fine on iOS7. I cannot use AutoLayout as I must support the app for older versions of iOS prior to 6 also. I tried setting the container view's frame if the iOS is of version 7 and above but it does not work. I also tried topLayOutGuide length and other tips mentioned in other SO posts but I could not succeed. (EDIT:- I am using STORYBOARD)
The only thing I currently have in my code is
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
Can someone please help me with this issue?
I try to suggest a change to do in the storyboard:
tap on your viewController and on attributes inspector uncheck Under top bars
if this not work try this code:
-(void)viewWillAppear:(BOOL)animated {
NSString *ver = [[UIDevice currentDevice] systemVersion];
int ver_int = [ver intValue];
if (ver_int < 7) {
}
else {
self.navigationController.navigationBar.translucent = NO;
}
}