iPhone 6 orientation transform issue - UIWindow object - ios

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.

Related

Launchscreen rotation not working on iPhone 6s and smaller screens

I have a launchscreen storyboard with an ImageView and two labels all with some constraints to align the objects relative to the size of the screen.
When i choose a device with a screensize of an iPhone 6s or smaller in the simulator and rotate the device in landscape mode the view is not rotated.
When selecting an device with a larger screensize, e.g. an iPhone 6S Plus, the launchscreen is rotated correctly in landscape mode. Also when running it on an iPhone 6 the launchscreen is not rotated.
Any suggestions how to resolve this?
Maybe got a little bit closer to the cause. When rotating an iPhone 6 Plus or larger to the left in the Simulator, the dock icons are rotated. These are not rotated when rotating a device with a screen size equal or smaller than the iPhone 6.
I do not believe it is possible to rotate the LaunchScreen.
On the Apple Developer site: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/ in the section on "Handling View Rotations" there was this line:
At launch time, apps should always set up their interface in a portrait orientation. After the application:didFinishLaunchingWithOptions: method returns, the app uses the view controller rotation mechanism described above to rotate the views to the appropriate orientation prior to showing the window.
So it looks like your main storyboard will get invoked before orientation can be taken into account.

Wrong width of view on startup of iPad app in iOS 7

If your device (simulator or iPad) is in landscape orientation and you start the app while querying the width you get wrong results. One should get 1024 but in fact I'm getting 768 which is completely wrong. On iOS 8 this does work as expected. On iPhone and iOS 7 the view is first in portrait but then changes quickly to landscape which works for my case.
In viewDidLoad I'm getting the the size with View.Bounds.Size.Width. If you rotate the device and query the data in didRotateFromInterfaceOrientation the data is correct. For my app I don't need this in viewDidLoad, but in another method. But in viewDidLoad it seems to be the same behavior.
What's wrong here? How do I get the correct width of the view on iOS 7 and iOS 8?
You should try getting the width in viewDidLayoutSubviews: or any other method that comes after that in the view hierarchy such as viewDidAppear:
Hope this helps you.

[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.

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

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;
}

Resources