[I know this has been done to death, and I'd ask follow up questions on an existing question were it not for not having enough stackoverflow points to make one:(]
I'm after an App Store valid way of forcing an existing UI to re-orientate without having to destroy the main ViewController or View. We work in fullscreen mode, so I'm assuming I can't use any of the toolbar approaches normally quoted. Finally I'm only interested in iOS5.
For iOS6 I have a solution based on the answers in How to change the device orientation programmatically in iOS 6. I used the solution which includes ForcePortrait, with the variation that I changed it so I can supply the required orientation as a parameter.
For iOS5 I have experimented with the suggestion of:
[UIDevice currentDevice] performSelector:NSSelectorFromString(#"setOrientation:") withObject:(id)UIInterfaceOrientationPortrait];
from How to set device (UI) orientation programmatically?. This works well but I'm worried that it would be rejected by App Store (complete no no for us).
Has anyone used this on something that has App Store approval and/or got a better suggestion?
Check this out: Force Rotate UIViewController.
Maybe it will work. This is however very hackish.
[Found a solution, at any rate. Not sure if it the best.]
Got the temporary UIViewController approach to work by adding shouldAutorotateToInterfaceOrientation. The meaning of this is overloaded by iOS5 to discover not only should it autoRotate but also should it start in a particular orientation to start with - I guess that is why it is replaced by several methods at iOS6.. Thus we return true in orientations that are OK.
Perhaps should have realised that before.
Not quite as neat as the setOrientation hack. Key glitch we've noticed is that when you then rotate the device around to the proper orientation you still get a rotation animation. This does not occur on iOS6. Oh well, you win some, you lose some.
Related
In one of my view controllers, I do this...
self.gridCamera.orientation = motion.gaze(atOrientation: UIApplication.shared.statusBarOrientation)
The function returns a SCNVector4 that aligns a SceneKit view with the proper "up".
UIApplication.shared is no longer allowed from outside the main thread. Instead of just calling it from a dispatch, can anyone suggest a different way to do it entirely? Is there a better way to get the orientation that isn't reliant on the UIApplication.shared?
UIDeviceOrientation seems to be reliant on UIDevice, which provides a representation of the current device.
Returns the physical orientation of the device.
This blog will help you on how to use UIDeviceOrientation to determine the applications orientation.
Using UIDeviceOrientation may not be the best way to get the
orientation of the views, but sometimes this is still needed.
Following this guide should help you get started, and most of the
time, this is all you will need. Just be sure to read through the
important points. Drop by in the comments section if this post helped.
when first entry, the result like this
App into the background and back, the orientation is normal
this is the code for the ViewController:
DDYLoveAutoHallViewController *autoHallViewController = [[DDYLoveAutoHallViewController alloc] initWithEvent:room.currentEventID type:AHRoom_System];
[self presentViewController:autoHallViewController animated:YES completion:nil];
i don't know why, the project is a litter old, it support iOS5 before.
Without understanding on how do you manage layouts it is difficult to give the exact reason, caused you problem, but, i can suggest you couple of little advices:
try to re-check orientation in - (void)viewDidLayoutSubviews, and you can re-position things from there. (probably it will work and solve your problem, but it is not very clean solution, because may be called a few times at time, knowing this you can make it cleaner)
play generally with the methods of layout-lifecycle, to detect where are things is going wrong. Dive deeper in modern way to layout on iOS. (better solution)
Without more details regarding your specific problem, and how you are detecting and adjusting the orientation, it is hard to understand the exact problem, but here are some observations I have made, working with iOS 5.x based (and earlier), apps, that might point you in the correct direction:
[1] Earlier versions of iOS set some defaults, before actually interrogating the hardware to determine orientation and app frame size information.
a) Initially orientation is set to PORTRAIT - along with portrait orientation frame dimensions - during initialization. (This is WRONG if you device is in landscape orientation - so DON’T USE this initial info). (left over from earlier “iPhone only days” - I guess)
b) This continues to be incorrect at the “ViewDidLoad” and “applicationDidBecomeActive” timeframes (at least for my app - possibly - depends on loading time etc…)
c) The correct orientation is yielded later, via the “didChangeStatusBarOrientation method invocation. You can use this information with Window.frame.size information, to display the correct image with the correct size.
This is effectively the trigger to indicate the orientation request will now be correct.
One stategy might be to : Don’t try to display anything until the “didChangeStatusBarOrientation” message has been received.
[2] Non-Code Solution: (using Settings : Supported interface Orientations)
a) If the app is designed to always work in the Landscape orientation, make sure this is reflected in the app settings/info.plist. I would suggest only allowing 1 “supported interface Orientations”, that being Landscape, and all views would reflect the landscape size and orientation.(if your code is not specifically setting or doing anything with orientation, then this might be a solution by setting everything to "landscape only". Otherwise this option probably won't help.)
[3] Last Solution:
a) If you can change the base iOS version higher, the iOS6 and greater versions initialize the orientation and frame sizes earlier in the initialization cycle, so the problem may just disappear due to this.
Here is some of the code used to discover this, along with output below (using an original ipad as a sample, in this case…running iOS 5.1.1 - started in landscape and orientation was unchanged)
-(void) OrientationAndScreenSizeHELPER : (NSString *)fromObject
{
//from:
// NSLog(#"%s:%d someObject=%#", __func__, __LINE__, someObject);
CGRect appFrame = [[UIScreen mainScreen ]applicationFrame];//using frame so status bar is not part of calculations.
appFrame = [[self.viewController view]frame];//using frame so status bar is not part of calculations.
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
NSLog(#"orientation[%ld] at time[%#] width[%ld] height[%ld]",
(long)orientation,
fromObject,
(long int)appFrame.size.width,
(long int)appFrame.size.height);
}
**Output:**
orientation[1] at time[ViewDidLoad Orientation] width[768] height[1024]
orientation[1] at time[applicationDidBecomeActive] width[768] height[1024]
orientation[3] at time[didChangeStatusBarOrientation] width[1024] height[768]
I'm writing an app in Swift 2.0. The app works fine in every aspect, beside one.
When I tilt the screen of both device and emulator the orientation change animation is missing. Instead of a smooth rotation I get a clunky orientation change. Portrait -> Landscape. Nothing in between.
Giving the fact that the animation should be the default, I would like to know if anybody knows the possible solution to this problem. I searched everywhere and apparently nobody has this problem, instead people try to disable that animation!
After some tests and thanks to Zell.B, I moved the code from didFinishLaunchWithOptions to applicationDidBecomeActive and everything works fine.
Deleting the applicationDidFinishLaunching method from the app delegate class can also cause the lack of animation problem. Adding it back in can fix it.
So I'm creating and showing a custom window in my iOS app because I'm writing a dynamic alert view that also functions like a growl/toast alert. It works AWESOMELY in ios6 (Hopefully I can open source this baby and you can all check it out)
But anyway, when I run this in ios5, the window that my alerts exist on doesn't seem to rotate with the device/simulator. No matter what, my custom window stays in portrait mode.
The UIWindow is just a UIView subclass, so there's no nice 'shouldRotate' delegate method.
I'm kinda stumped on why this is happening in ios5 but not 6. Any help would be GREATLY appreciated ^_^
My window has a rootviewcontroller, which I completely forgot about. I just needed to implement
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
return YES;
}
To get it to work.
:-D
It's usually not recommended two use multiple instances of UIWindow in one iOS app. The only valid reason to do so is to support external screens. You should use a UIView instead, ideally managed by a UIViewController.
I assume, (since you didn't provide any code, I can only assume) the reason why your window doesn't 'rotate' is, that it's simply not getting any notifications about device rotation. Only the keyWindow receives them by default.
I would highly recommend to redesign your app to use a properly managed UIView instead. If you desperately don't want that for some reason, you would have to register your instance of UIWindow to receive the UIDeviceOrientationDidChangeNotification and then (in the handler) evaluate what the new orientation is and change the window's frame accordingly (plus maybe other things that need to be done in response to the orientation change)
Since iOS 6 release, there are some iAd properties and methods that are deprecated like :
currentContentSizeIdentifier
requiredContentSizeIdentifiers
ADBannerContentSizeIdentifierPortrait
ADBannerContentSizeIdentifierLandscape
So what's the best way to implement iAd now on both orientation ? Should we now resize the banner view frame manually ?
I have my application only support Landscape mode(should work for Portrait mode also), and have iAd showing up on the top of the application. And to make this work with ios6 I had to do this:
In Monotouch
storesAdBannerView = new ADBannerView();
storesAdBannerView.AutoresizingMask = UIViewAutoresizing.FlexibleWidth;
For objc (which I dont use), I think it might be
[storesAdBannerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth]
It seems that landscape ads are somewhat phased out.
See: http://www.iphonedevsdk.com/forum/iphone-sdk-development/108118-landscape-iad-banners-in-ios-6-edit-landscape-phased-out-completely.html
It need further confirmation, as I could not find any Apple document regarding that change.
I sAw 2 workaround there : http://www.touch-code-magazine.com/iad-code-is-broken-in-ios6/ Tested the first solution:
easy temporary solution – you can quickly get your app to compile again by using a cheap cheat, add explicitly #import to the files where you are accessing currentContentSizeIdentifier and the size name constants. That should get you going until you alter your app to use the new auto-layout features.
It works ok on xcode 4.5 (banner test ok).