iOS 13: Orientation Change Between Portrait/Landscape Causes Black Area to Cover Part of Screen

I’m using XCode 11.1 and building/testing an app that automatically resizes on orientation changes. When I test the app on a tablet running iOS 12 it works fine, but on a device with iOS 13 I get a black bar on the right side of the screen when the layout changes from portrait to landscape:

screenshot2

A similar thing happens when the device rotates from landscape to portrait orientation–in this case the black area is at the bottom. It looks like the app is getting the correct width/height information in the resized() callbacks and the layout is being adjusted propertly, and that the black area is covering part of the screen. When I print out the width/height of the app’s main window (juce::DocumentWindow) and the app’s main component, the sizes reported are correct (the width/height flip after the orientation change and reflect the size of the entire screen). When I try this in the iOS simulator I get the same behavior (but only when the orientation changes from portrait to landscape–the black area doesn’t appear at the bottom when going the other way).

I think this is probably an iOS 13 issue, but I’m not entirely sure. I’m using JUCE 5.4.5 with the latest Projucer. I’m setting setFullScreen(true) and setResizable(true, false) on the main window, but these don’t seem to have any effect (these were mentioned in similar forum posts a while back).

Does anyone have any idea what’s happening and how to fix it?

Maybe try to Implement your own handlers for iOS rotations?

Thanks, that could help if I need to write a workaround…

I did a little debugging… This is a printout of all the native UIViews and their frame coordinates when the app is initially in portrait orientation on the iOS simulator (the indentation shows the hierarchy, so the UIDropShadowView is the top-level view found in [[[UIApplication sharedApplication] keyWindow] subviews]):

 PRINTING ALL NATIVE VIEWS
 UIDropShadowView {{0, 0}, {768, 1024}}
   JuceUIView {{0, 0}, {768, 1024}}
     UITextView {{0, 0}, {0, 0}}
       _UITextContainerView {{0, 0}, {0, 30}}
         _UITextViewCanvasView {{0, 0}, {0, 30}}
         UITextSelectionView {{0, 0}, {0, 0}}
       _UIScrollViewScrollIndicator {{-42, -6}, {36, 3}}
         UIView {{0, 0}, {36, 3}}
       _UIScrollViewScrollIndicator {{-6, -31}, {3, 28}}
         UIView {{0, 0}, {3, 28}}

After an orientation change the printout looks like this:

 PRINTING ALL NATIVE VIEWS
 UIDropShadowView {{0, 0}, {768, 1024}}
   JuceUIView {{0, 0}, {1024, 768}}
     UITextView {{0, 0}, {0, 0}}
       _UITextContainerView {{0, 0}, {0, 30}}
         _UITextViewCanvasView {{0, 0}, {0, 30}}
         UITextSelectionView {{0, 0}, {0, 0}}
       _UIScrollViewScrollIndicator {{-42, -6}, {36, 3}}
         UIView {{0, 0}, {36, 3}}
       _UIScrollViewScrollIndicator {{-6, -31}, {3, 28}}
         UIView {{0, 0}, {3, 28}}

So the UIDropShadowView didn’t change it’s frame width/height… That might be what’s cropping the image on the screen.

1 Like

interesting.
I wonder if there is a missing “resized()” call…

hopefully the JUCE team sees your discovery.

FWIW I can also confirm this behavior, on iOS 13.2 and Xcode 11.2 beta 2. On iPhones, half the screen gets blacked out in landscape mode.

I get the following in the Xcode console:

[Window] Manually adding the rootViewController’s view to the view hierarchy is no longer supported. Please allow UIWindow to add the rootViewController’s view to the view hierarchy itself.

No such problems with iOS 12.

Actually, it’s a UITransitionView + its UIDropShadowView subview that doesn’t flip its width/height (I was missing the top one in my printout):

 PRINTING ALL NATIVE VIEWS
 UITransitionView {{0, 0}, {768, 1024}}
   UIDropShadowView {{0, 0}, {768, 1024}}
     JuceUIView {{0, 0}, {1024, 768}}
       UITextView {{0, 0}, {0, 0}}
         _UITextContainerView {{0, 0}, {0, 30}}
           _UITextViewCanvasView {{0, 0}, {0, 30}}
           UITextSelectionView {{0, 0}, {0, 0}}
         _UIScrollViewScrollIndicator {{-42, -6}, {36, 3}}
           UIView {{0, 0}, {36, 3}}
         _UIScrollViewScrollIndicator {{-6, -31}, {3, 28}}
           UIView {{0, 0}, {3, 28}}

Anyway I wrote a kludge that finds the JuceUIView object, gets the frame property from that, then goes to all of its parents (the UITransitionView and UIDropShadowView) and resets the frame properties of those to the correct frame that it got from JuceUIView… and that made the black bar go away.

I’ll poke around a little bit more in JUCE’s objective c code, maybe I can find the real source of the problem (I guess it might be how the root controller view is added–I get the same warning)… I’ll post whatever kludge or solution I come up with.

@t0m @jules this seems like a pretty high-level bug for iOS devs using JUCE!

Maybe the workaround proposed in iOS Multitasking also helps in this case?

Hi RomanS, yes that fix of mine seems to cover it. Pete

1 Like

This should now be fixed in 8d75cc8.

2 Likes

The fix on develop works, thanks!

this fixed it for me too, thanks.