Is this an iOS 8 Bug (orientation issue on rotation)? - ios

since iOS 8 my App runs quite good, but I found a Problem while testing this app.
It just happens on iPad and only if I launch the app in landscape mode. If it launches in Portrait everything is right(no rotation issues). If i rotate the Device (simulator or real device) the view rotates out of the screen and just shows a Cut of the real view and the rest is black.
Anyone else did notice such a bug? How can I fix it?

Had similar problem. Surprisingly the fix was to comment out all the code related to self.window on Appdelegate.
Commented initialising of self.window and its assignment. Set the initial view in storyboard in Attributes inspector by checking "Is Initial View Controller" checkbox.
New Better Solution
Commenting self.window was causing other issues. Instead the below code is best:
- (void)applicationDidChangeStatusBarOrientation:(NSNotification *)notification
{
[UIViewController attemptRotationToDeviceOrientation];
}

UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
BOOL landscape = (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight);
NSLog(#"Currently landscape: %#, width: %.2f, height: %.2f",
(landscape ? #"Yes" : #"No"),
[[UIScreen mainScreen] bounds].size.width,
[[UIScreen mainScreen] bounds].size.height);
And the results are:
For iOS 8+
Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 568.00, height: 320.00
and for iOS 7-
Currently landscape: No, width: 320.00, height: 568.00
Currently landscape: Yes, width: 320.00, height: 568.00
It seems like there is a change in the way height and width of the screen is handled while in portrait and landscape from ios8 onwards.
Check this link
Is [UIScreen mainScreen].bounds.size becoming orientation-dependent in iOS8?

UPDATE - We found a fix:
I found the answer to our problem which as described below appeared to be exactly the same as yours. One of our other developers noticed an "unexpected nil in main window" when attempting to tap on the far right of the screen. This led me to do a new search and I found this thread on stackoverflow that actually contained the answer to our problem.
( here is the link to the question which help my answer: unexpected nil window in _UIApplicationHandleEventFromQueueEvent )
The actual answer came from frankish who suggested opening the main.xib (or main storyboard) and clicking on the Window in that and making sure that the "Visible at Launch" and "Full screen at Launch" properties are checked (set to true.)
In our case, it was JUST the "Full screen at Launch" property that needed to be set, but setting this fixed the rotation problem we were seeing AND it fixed an issue where when launching on iPad in landscape the far right of the screen was not touchable.
END UPDATE - (original non-answer below)
My answer isn't an answer, but I have run into the exact same issue. On rotate in our app, when building with Xcode 6, I see the exact same rendering issue as the the screenshots on this question. The exact same out of position rotate with black bars at the side and bottom. (Our app on iPhone doesn't support any rotation so we don't see the issue on iPhone. On iPad we support landscape left and landscape right. When rotating from one to the other, when the iPad does it's standard rotation animation, it will rotate out of position (showing the black bars) when going one way and then rotate back into proper position when going back to the other supported orientation. I don't believe it's related to any custom positioning or animation code. It happens with every screen, including the splash screen. It appears to be related to the built in Apple screen rotation. Obviously not every project has this issue in iOS but I have not come across the particulars that are causing this issue. I spent all day yesterday researching the issue and going through our code and I have nothing.
One piece of additional info. If I build with Xcode 6 and run on a device with iOS 7 then there is not issue. This issue ONLY happens when I build with Xcode 6 and run on a device with iOS 8.
Here is a link to my own question posted yesterday about this issue. (I did not come across this question until after I'd posted my question.)
Building project with Xcode 6 (iOS 8 SDK) causes landscape rotation rendering issue on iPad

I found this to be an issue when I had multiple windows in my application. By setting a breakpoint on -[UIWindow setFrame:], I was able to see that upon rotation, the system was giving me giving me an erroneous frame size and position. You can get around this by manually setting your frame to equal [UIScreen mainScreen] bounds] which seems to be correct if you running on iOS7+ and compiling with Xcode6. I found that doing this in -[UIWindow becomeKeyWindow] worked well for me:
- (void)becomeKeyWindow {
[super becomeKeyWindow];
self.frame = [UIScreen mainScreen].bounds;
}

Related

[UIScreen mainScreen].bounds Different iOS 8?

I just started testing my app on an iPad 2 thats still running iOS 7, because thats what I had lying around. As soon as I open up the app, the main view under the UINavigationController is offset and too small. Heres a picture of what I'm talking about:
The whole screen should be the light color. I use [UIScreen mainScreen].bounds to make the lighter view. I'm compiling this on the iOS 8.2 SDK. After logging the width and height, it seems like they're inverted. Is that how iOS 7 handles things? I think just checking if its running iOS 7 and swapping them will work, but I want to make sure this is the problem. Thanks.
EDIT:
Swapping them worked, but when I go to another view, that view is also rotated, and those are normal views.
iOS8 bounds are relative to orientation thus a device in landscape will have different bounds from the same one on portrait , in iOS7 this does not happen, the bounds are the same no matter if you are in portrait or landscape
See this answer

Xcode 6 iOS 7 view size

My root view controller is a tab view controller. My app is landscape mode only. It's set on landscape both in the project settings and in the storyboard for each VC including the root. In viewDidLoad, I have:
NSLog(#"width of view in didappear:%f",self.view.frame.size.width);
and the same code in viewDidAppear. In viewDidLoad in iOS 8, that line prints out 480. In iOs 7, it prints out 320(the width of the screen in portrait mode) but in viewDidAppear, it prints out 480 which is correct. Yes it is the same device for all of you out there who are always in search of 'precise' details.
Why is the view still in portrait in viewDidLoad in ios7 but not in ios8? What can be done? I set up my whole view in viewDidLoad because I only need to do it once and so can't migrate it to viewDidAppear or other places.
It's a curious difference between iOS 7 and 8 if that's the case. I'm guessing it's the same device type but physically different items? Or are you really running iOS 7 & 8 on the same device?
So you could theoretically still have setting differences. I.e. iOS 7 device locked in portrait, etc.
If the setup is really as you say, a boolean property would help you to run in viewDidAppear. I just provided an example of how that could be done here: https://stackoverflow.com/a/27867549/1111233
Basically, viewDidLoad is run before the UIElements are loaded and placed on screen, so that's why you are getting the wrong size. As far as the difference between iOS7 and iOS8, I guess apple slightly changed the internals, but in any case you should definitely move your graphics code to viewWillAppear. viewWillAppear is run when the graphics are loaded and works the same as viewDidLoad
use bounds
CGRect rect = [[UIScreen mainScreen] bounds];
NSLog(#"width of view in didappear:%f",rect.size.width);
The frame is relevant to the parent view. The very top view is UIWindow, which in iOS 8 became rotation dependent. In landscape the frame and the bounds will therefore be different in iOS 7, but the same in iOS 8. If you use bounds instead of frame, it should give the same result for both iOS versions, given that the objects are not rotated some number of degrees.

iOS 8 Orientation Issues : Keyboard ends up in incorrect position

I have a universal project for iOS that was created in xCode 5 that I am trying to port to xCode 6. Everything seems to have been fine since I am not using LaunchScreen and iPhone 6 and 6 Plus scale the application to their resolutions.
The problem occurs when device changes its orientation.
Scenario:
It only occurs on iPhone 6 and 6 Plus.
Open Login screen with username and password fields. Rotate the device to Landscape, and tap username or password field. The keyboard appears in the middle of the screen with half cut. Rotating back to portrait hides the keyboard altogether and it no longer appears on screen no matter which field you tap on.
To get the keyboard back, rotate back to Landscape, tap on a field rotate device to opposite Landscape (don't let it go in Portrait). The keyboard suddenly becomes normal and acts fine.
I got the same problem, and that's because your app is launched in scaled mode.
It seems that Apple didn't go the full blown way to handle landscape in this scaled mode.
The solution is to switch to non-scaled mode for the iPhone 6-6Plus, using the trick specified here: How to enable native resolution for apps on iPhone 6 and 6 Plus?
Note that this will likely break a lot of your screens in the process.. but there's no other solution.
I have faced this issue with scalable mode of the app. Though supporting non-scalble mode (by adding iPhone 6 & 6+ launch images to xcassets) solves this problem, it was not permissible in my case as screens had static layout for each orientation.
I could solve this problem by avoiding the incidents of changing the root view controller of the window. Instead, the new view controllers have been added (with balancing removal) as subview (and hence childViewController) to the existing root view controller.
Everything is ok on iOS6/7, But not iOS8.
The orientation of the keyboard on iOS 8 is not the same as status bar.
If your application runs only portrait mode you can stop generating orientation notifications;
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
I have faced this issue, and after some research I found some stuff, that caused such bug.
In my AppDelegate I changed window rootViewController to show different ViewControllers depends of authorization status
if (!auth)
{
self.window.rootViewController = [[AuthViewController alloc] init];
} else {
self.window.rootViewController = [[DataViewController alloc] init];
}
I removed this and move controller select logic to NavigationViewController
if (!auth)
{
self.viewControllers = #[[[AuthViewController alloc] init]];
} else {
self.viewControllers = #[[[DataViewController alloc] init]];
}
and make this NavigationViewController as Storyboard initial view controller.
Hope it helps!

iPhone 6 orientation transform issue - UIWindow object

I found the issue while trying to update our project to adapt the change in iOS8 and iPhone6. After a series of testing and debugging, I do not know the reason that causes this issue. Only clue I found is that when creating UIWindow object in iPhone6, landscape, the UIWindow object has different angle (orientation) than the main screen (status bar angle). And after trying to transform the UIWindow object, it actually goes to a weird size. I do not know why and how this is happening. Your help is highly appreciated!!
[Environment]
Xcode 6.0.1
build 6A317
simulator: iPhone 6, iPhone 6+
[Issue]
There’s weird behavior occurred when trying to resize the UIWindow object to full screen (frame = [UIScreen mainScreen].bounds )
[Normal Behavior] (OK)
1. Create UIWindow object in portrait orientation
2. Turn the device to landscape
3. UIWindow object will be resized to full screen
4. Resize OK
[Abnormal behavior] (FAIL)
1. Create UIWindow object in landscape orientation
2. UIWindow object size correct, but orientation is wrong
3. After trying to transform to correct angle(orientation), the frame origin/size is messed up
[Test Result]
Testing simulator: iPhone 4s, iPhone 5, iPhone 5s, iPhone 6, iPhone 6+
Environment: Xcode 6.0.1, build 6A317, iOS8 simulator
Screenshots link
I have exactly the same issue after I upgrade my project to the new SDK and new device.
Just by adding an empty storyborad as launch screen in the project setting fixed this issue for me:
Had the same problem. Turns out I was calling initWithFrame on UIWindow with CGRect in pixels instead of points.

statusBarFrame.height returns 1024.0 when in Landscape (iPad)

I have been using the following code to get the height of the status bar:
[UIApplication sharedApplication].statusBarFrame.size.height
This works perfectly in Portrait mode and returns the expected value (20.0), but when the application is in Landscape, I get the unexpected value of 1024.0 !!
Is anybody able to shed any light on this for me?
iOS version 6.1.3
XCode version 4.6.2
Use this if you want to forget about orientation or coordinates related problems:
float statusBarHeight = MIN([UIApplication sharedApplication].statusBarFrame.size.height, [UIApplication sharedApplication].statusBarFrame.size.width);
You might need to use the [UIApplication sharedApplication].statusBarFrame.size.width on Landscape orientation. Same as [[UIScreen mainScreen] applicationFrame] gives switched values on Landscape orientation
This is completely correct. The statusBarFrame is in screen coordinates.
You have to use statusBarOrientation to check whether you should switch the coordinates.
At what point in the app do you get this?
If it's at first run, check what orientation your .xib files are in in the project. If they are in portrait then even though the app is started in landscape it hasn't had time to determine orientation and uses the dimensions of the .xib that it's creating the frontmost view controllers view from.
In iOS 6 the rotation handling and orientation detection changed
significantly from iOS 5 and lower, I beleive that you can no longer
rely on the orientation of the status bar for these values.
this may help
You don't need to check for the orientation, just use the UIView convenient method for converting the frame:
CGRect statusBarFrame = [self.view convertRect:[[UIApplication sharedApplication] statusBarFrame] fromView:self.view.window];
Clean Build your code and check whether orientationChange methods are called.
Please specify the iOS version as well

Resources