1

I am updating an iOS 6 app to iOS 8 (iPad), and any new UIWindows that I create are always showing up in Portrait mode. The app originally supported both the Portrait and Landscape orientations but now will only support Landscape.

I've changed the supported orientations in the project file to Landscape Left and Landscape Right. The entire UI shows up in landscape, as expected, but when I create a new UIWindow, it shows up in portrait. The new UIWindow's frame matches the screen's frame exactly, so I can't imagine why/how it is showing up in portrait mode.

The following code is what I am using to create and show the new UIWindow, which acts as a modal:

var modalWindow:UIWindow = UIWindow(frame: self.view.window!.bounds)

modalWindow.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.66)
modalWindow.hidden = false
modalWindow.windowLevel = (UIWindowLevelStatusBar + 1)

modalWindow.addSubview(customView)    

modalWindow.makeKeyAndVisible()

I've been struggling with this for a few hours; shouldn't the UIWindow be in landscape mode by default since the app only supports the Landscape orientation?

I would greatly appreciate any advice on how to resolve this issue.

EDIT:

I just created a new test app that only supports Landscape Left and Landscape Right, and the issue occurs there as well. Is this a bug? I can't seem to understand why the UIWindow would think the app is in Portrait mode when it's in Landscape mode.

Alexander
  • 3,959
  • 2
  • 31
  • 58
  • Are you supporting iOS 8+ only or are you supporting iOS 7? If you are, can you test it on that simulator? I suspect it will work and I know why. – Acey Nov 13 '14 at 18:55
  • The deployment target is iOS 8.0, but my plans are to support iOS 7+ and iOS 8+. I've just tried changing the deployment target to iOS 7.0, and the `UIWindow` is still in portrait mode. Is that what you meant by "that simulator"? – Alexander Nov 13 '14 at 19:03
  • Maybe to step back, why are you using UIWindows for modal presentation? In iOS 7, great new APIs were made available to custom modal presentation. I suggest checking that out first: https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UIViewControllerTransitioningDelegate_protocol/index.html – Acey Nov 13 '14 at 19:07
  • I am using UIWindows because I am working with a custom view and not a separate view controller. I would also like to position the custom view wherever I'd like on the screen. – Alexander Nov 13 '14 at 19:09
  • No that isn't what I meant by that simulator. You'll need to download the iOS 7.1 simulator from Xcode Settings -> Downloads. Anyhow, the issue is that in iOS 8, UIScreen and the main window return orientation based bounds and frames. Before, you would always get/set the orientation in portrait, now it depends on your orientation. I believe this is the issue. – Acey Nov 13 '14 at 19:18
  • Thanks for your reply, Acey! How might I fix this issue? When I output the frame of the new UIWindow, it is equal to the bounds of the main UIScreen in the landscape orientation. – Alexander Nov 13 '14 at 19:57
  • Just an update on this: I created a brand new iOS 8.1 project in Xcode, and the issue occurs on the new project as well. I tested with the iOS 7.1 simulator but received the same results. However, the UIWindow correctly covers the entire screen on 7.1 but not on 8.1. I found out that the `size` of the screen is equal to its portrait dimensions, while its `frame` is equal to its landscape dimensions. I can't change its `size`, though, so I am still hoping for some additional help. – Alexander Nov 17 '14 at 13:55
  • Here's the same help I suggested before: stop using UIWindow and start using the presentViewController related APIs. – Acey Nov 17 '14 at 16:52
  • i have the same problem with the rotation (http://stackoverflow.com/questions/26976494/ios-8-7-uiwindow-with-uiwindowlevelstatusbar-rotation-issue) @acey could you perhaps demonstrate how to present another view/window over status bar and how handle rotation? – Hashmat Khalil Nov 18 '14 at 08:05

1 Answers1

3

EDIT (July 2, 2015)

This answer breaks in iOS 8.3+ and possibly previous versions of iOS 8. I DO NOT recommend that anyone uses it, especially since it is not guaranteed to work in future iOS versions.

My new solution uses the standard presentViewController method of a UIViewController. I initialize a UIViewController, add my custom modal View as a subview of the UIViewController, and then position the modal View using constraints. Works like a charm!


Original Answer

I left this for a while but decided to come back to it today. I ended up rotating the modal window -90 degrees since it is automatically rotated 90 degrees to be displayed in portrait. I also added a small calculation for the modal window's width and height to support both iOS 7 and iOS 8. Here is my new code:

// Get the screen size
var screenSize:CGSize = UIScreen.mainScreen().bounds.size

// Use the larger value of the width and the height since the width should be larger in Landscape
// This is needed to support iOS 7 since iOS 8 changed how the screen bounds are calculated
var widthToUse:CGFloat = (screenSize.width > screenSize.height) ? screenSize.width : screenSize.height

// Use the remaining value (width or height) as the height
var heightToUse:CGFloat = (widthToUse == screenSize.width ? screenSize.height : screenSize.width)

// Create a new modal window, which will take up the entire space of the screen
var modalWindow:UIWindow = UIWindow(frame: CGRect(x: 0, y: 0, width: widthToUse, height: heightToUse))

modalWindow.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.66)
modalWindow.hidden = false
modalWindow.windowLevel = (UIWindowLevelStatusBar + 1)

modalWindow.addSubview(customView)    

// Create a -90 degree transform since the modal is always displayed in portrait for some reason
var newTransform:CGAffineTransform = CGAffineTransformMakeRotation(CGFloat(-M_PI / 2))

// Set the transform on the modal window
modalWindow.transform = newTransform

// Set the X and Y position of the modal window to 0
modalWindow.frame.origin.x = 0
modalWindow.frame.origin.y = 0

modalWindow.makeKeyAndVisible()

As stated, this works great on both iOS 7+ and iOS 8+! When working with subviews, note that the modal's width and height values are switched since it's displaying in portrait. So, if you want to center a subview horizontally, use the modal window's height and the subview's width instead of both views' width.

Alexander
  • 3,959
  • 2
  • 31
  • 58
  • Hi, I have the same issue. I have created a custom taost message and I add this to a custom `UIWindow`. Everything works great. but it fails only on iPad3 (iOS 8.3) landscape mode. Any idea? – Suryakant Sharma Jun 30 '16 at 06:02