ViewController offset after device rotation in iOS8

此生再无相见时 提交于 2020-01-17 05:16:06

问题


I am experiencing an odd problem with legacy code running in iOS8. The code was originally written pre-iOS6, pre-storyboards (using nibs) and functioned without issue on iOS7. However, strange behavior began to occur when running on iOS8.

The app is set to run only in landscape (left or right). Therefore it should support autoRotation from landscape-left to landscape-right. The first problem was that the initial view controller was loaded in portrait and one side was cut off. This issue was addressed with the following code in the AppDelegate:

self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]];

Changing the order of these calls allowed the view controller to load in its proper orientation and did not affect apps running in iOS7. However, now when the device is rotated 180 degrees I get the following results. See images...

Here is the app at initial load:

And after a 180 degree rotation, I get this offset effect:

Any ideas on how to address this issue? Again, everything is fine in iOS7 or previous. THanks!


回答1:


I had a problem just like yours when iOS 8 first appeared, and it had nothing to do with the opening window-creation incantation! It has to do with your Info.plist. It is crucial that the first orientation listed in the Info.plist be an orientation that the root view controller actually permits.

So, let's say your root view controller permits only landscape. Then you will get the problem you describe if your Info.plist looks like this:

<key>UISupportedInterfaceOrientations</key>
<array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
</array>

See the bug? Portrait comes first. No. If the root view controller permits only landscape, then one of the landscape orientations must come first.

[You can actually see me experiencing the issue, then discovering and reporting the solution, here: https://stackoverflow.com/a/24467576/341994]


Also, I have to wonder whether you might be doing anything else that upsets the rotation system. Note that the nature of rotation itself, including the coordinate system, what rotates, when it rotates, etc., has completely changed in iOS 8; this is probably the biggest single change in iOS 8. So if you have old code that makes under-the-hood assumptions about what rotation is (e.g. that it involves a transform), that code will now break. You do not show any of that in your question so I can't provide specifics about what you might be doing.


Finally, just for the record, the correct minimal opening incantation is (this is Swift code but I'm sure you can translate):

func application(application: UIApplication, 
    didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    self.window!.rootViewController = UIViewController() // or whatever it is
    self.window!.backgroundColor = UIColor.whiteColor()
    self.window!.makeKeyAndVisible()
    return true
}



回答2:


You should use some autolayout constraints on the view controller so that it sticks to the left / upper and bottom of the parent container.




回答3:


Here are a few ideas:

1) Initialize your window with a frame, don't set it afterwards

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

2) Make sure the autoresizingMask of your rootViewController's view is FlexibleWidth+FlexibleHeight and you don't have flexible margins anywhere in there.

3) Make sure your App's target explicitly has only the orientations you want in the General->Deployment Info section. It sounds like you have it only going into the orientations you want, but just check that to make sure!




回答4:


I wasted a whole day with a similar problem while migrating our App from iOS 7.x to iOS 8.4. The views had mystic offset an wrong size after device rotation.

Our App uses a UITabBarController as RootViewController and the number of Tabs can change dynamically. On the iPad all views support all orientations. On the iPhone, only one view can be rotated, all other are firmly set to portrait. Because the number of views can change dynamically, I have a property that stores the possible orientations for each view. I return the content of the property every time UIViewController.supportedInterfaceOrientations() was called from iOS.

While debugging the problem I noticed that the function UIViewController.supportedInterfaceOrientations() was called immediately after AppDelegate called the function UIWindow.MakeKeyAndVisible(). At this time, my code had no chance to initialize the property, so UIViewController.suppoertedInterfaceOrientations() returned 0 to iOS. After i changed the code so that my property is initialized before UIWindow.MakeKeyAndVisible() was called, the mystic size and offset problem was gone!!!

My conclusion: Don't mess the iOS with a wrong or missing UIViewController.supportedInterfaceOrientations() function ;-)



来源:https://stackoverflow.com/questions/26811845/viewcontroller-offset-after-device-rotation-in-ios8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!