首页 > 代码库 > iOS Orientation bug

iOS Orientation bug

Every September now, means pain for the iOS developers. Because you need not only to update to the latest iOS system, but also to support old iOS versions with newer version SDK. More stuff coming, equally amount of stuff deprecated.

This bug I encountered is iOS 6.0 only, because game center only has portrait view, it will break landscape only games because they don‘t support the orientation.

Xcode will error out something about autoRotate which isn‘t the real cause.

People say apple fixed this bug for later version of iOS 6. but the workaround for this issue is to support Portrait view in UIWindow, but limit the rootViewController by setting up the landscape mask. 

In order to access a UIApplication, we need to do it from UIApplicationDelegate, the delegate class has a UIWindow, and the UIWindow has a rootViewController (after iOS 4.0), and you can add your UIView as subview to rootViewController.

This is quite normal for any 2D based display system, you will need to have a display container hierarchy anyway.

Everything works fine, problem seems to solved.

 

However, google mobile ad sdk interstitial triggered this rotation malfunction. Some interstitials have both landscape view and portrait view, even thought the interstitial starts with the current orientation, if you rotates, it will automatically sync. Since we have enabled the portrait view in UIWindow, now this interstitial could rotate. It‘s fine, BUT when you close it, the game mistakely got rotated, even tho the rootViewController only has landscape views. 

 

For some reason the interstitial is added to UIWindow directly, instead of add to rootViewController like banners do. Part of the reason might be the Google Mob Ad Sdk interstitial class is not derived from UIViewController, instead it derived from NSObjects directly. Anyway, I tried to add the InterstialViewController directly to rootViewController and presentViewController, the interstitial is cut off only showing up 1/3 of the screen. In another trial, the UI input is disabled. After all, both ways ended up with the interstitial is still rotatable, which causing the game play to rotate.

 

Some people suggested to use UINavigationController and set those rotation related functions. It doesn‘t seem to work since this app is really really really fucking old, it isn‘t even using Storyboard at all. Tried to change class declaration for rootViewController or interstialViewController, no luck.

 

What makes it even harder to debug is, if this is a native or modern iOS app, i could do everything in the project, adding flags checks. But this app is using our internal framework, AppDelegate is a static libarary class, otherwise i could add a game center flag check directly and control the supportedOrientation for window accordingly.

 

Plus, certain functions, for example the accelerometer and rotation function made by the framwork group seems to be working in parallel with the iOS system level function, but they are out of sync, the core functions cannot detect the portrait orientation, it simply ignores it! 

 

So after digging out more stackoverflow posts, people mentioned using setOrientation, or manually change the rotation. This is an unofficial or non-public interface, people still doing it. We cannot depend everything on iOS itself. So my final solution for this is: in willDissmissInterstitial function, manually rotate the window 90 degree secretly.  This works fine, nobody knows until i tell them.  (btw, if you put it in didDismiss function, you will notice a glitch)

 

So..Anyway, just to log what i did. The end of a 3 day torture.

 

iOS Orientation bug