UISearchController: Status Bar on top of Search Bar after rotating

Originator:matej
Number:rdar://21743785 Date Originated:09-Jul-2015 01:48 PM
Status:Open Resolved:
Product:iOS Product Version:iOS 8.3, iOS 9
Classification:UI/Usability Reproducible:Always
 
Summary:

IMPORTANT - this is essentially a duplicate of rdar://352525, but contains some more infomation about the exact cause of the problem (see “Notes”). 

If the device is rotated while a controller with an active UISearchController is offscreen (for example if it isn’t the top view controller in a navigation controller stack), UISearchBar layout breaks when returning back to the controller. See the attached search-controller-issue.gif for a visual representation of the problem. 

Steps to Reproduce:

See rdar://352525 and the attached sample project. 

Expected Results:

The status bar would never overlap the search bar text field. Instead search bar would keep the extended top-attached UI. 

Actual Results:

The status bar overlaps the search bar text field. 

Regression:

The same problem occurs on both iPhone and iPad on iOS 8 and iOS 9. It occurs regardless of the starting orientation (landscape or portrait). This is NOT related to the status bar being hidden in landscape on iOS 8+.

Notes:

The issue seems to arise in -[UIViewController _viewControllerUnderlapsStatusBar]. This method gets queried by UISearchController helpers to lay out the search bar during bounds changes, including rotation. 

In some cases the method caches previous results using two private flags (_viewControllerFlags.freezeShouldUnderlapUnderStatusBar and _viewControllerFlags.previousShouldUnderlapUnderStatusBar). When the presenting view controller is offscreen the cached values are NOT used and the overlap is computed explicitly. Since the presenting view controller view is not currently added to the view hierarchy (view.window == nil), the method can’t calculate the overlap and returns NO, which causes the status bar to assume the non-top-attached appearance. 

When the presenting view controller again becomes visible -[UIViewController _viewControllerUnderlapsStatusBar] is not queried again to update the status bar appearance. In addition, if we try rotating to force an update, the implementation now uses the cached value from _viewControllerFlags.previousShouldUnderlapUnderStatusBar, preventing the overlap from being computed. 

It’s possible to work around this problem by making sure -[UIViewController _viewControllerUnderlapsStatusBar] returns the cached value while the presented view controller view.window isn’t available, however that would be considered accessing private API and thus isn’t a viable option.

Comments

GIF

http://cl.ly/image/3K3B2R142C3D


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!