Nicholas Smith Nicholas Smith - 4 months ago 160
iOS Question

iOS 7: UITableView shows under status bar

The first screen of my application is a

UITableViewController
without a navigation bar, which means that the content flows under the status bar so there's a lot of text collisions. I've adjusted both the properties for
Under top bars
and
Adjust scroll view insets
which do actually stop it from scrolling under, but at the cost of keeping the top of the table view under. I've attempted to set the
UITableView
frame to offset by 20 pixels, but it doesn't appear to take effect and as I currently need the app to be compatible with iOS 6 I can't jump to iOS 7 Storyboards to force autolayout to use the top height guide. Has anyone found a solution that works for both versions?

Things I've tried: setting
edgesForExtendedLayout
, changing the settings within Storyboard for
Under top bars
and
Adjust scroll view
, forcing the frame to a new area.

A picture is worth a thousand words:
Status bar flow under

Answer

For anyone interested in replicating this, this problem is very easy to replicate: create a new project and delete the default ViewController and replace it with a TableViewController that you drag into the Storyboard from the Object Library. If you follow these steps, you will see that nothing, including tweaking Xcode's checkboxes to "Extend Edges Under {Top, Bottom, Opaque} Bars", as well as using

self.edgesForExtendedLayout=UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;

will place the UITableView below the status bar.

This issue can be very frustrating, and I believe it is a bug on Apple's end, especially because it shows up in their own pre-wired TableViewController from the object library.

I disagree with everyone who is trying to solve this by using any form of "Magic Numbers" e.g. "use a delta of 20px". This kind of tightly coupled programming is definitely not what Apple wants us to do here.

I have discovered two solutions to this problem:

  • Preserving the TableViewController's scene: If you would like to keep the TableViewController in Storyboard, without manually placing it into another view, you can embed the TableViewController in a Navigation Controller (Editor > Embed In > Navigation Controller) and uncheck "Shows Navigation Bar". This solves the issue with no extra tweaking needed, and it also preserves you TableViewController's scene in the storyboard

  • Using AutoLayout and embedding the TableView into another view (I believe this is how Apple wants us to do this): Create an empty ViewController and drag your UITableView in it. Then, Ctrl-drag from your TableView towards the status bar. As the mouse gets to the bottom of the status bar, you will see an Autolayout bubble that says "Top Layout Guide". Release the mouse and choose "Vertical Spacing". That will tell the layout system to place it right below the status bar.

I have tested both ways on an empty application and they both work. You may need to do some extra tweaking to make them work for your project.

Comments