34

My root controller is a TabBarController (tabbed application). One of the tabs, is a UITableViewController. When I switch to that and scroll through the items, they show up under the status bar at the top (signal, battery, etc). I don't want that. I want that to be opaque or... something. It's visually jarring with the text of the table cells underlapping the status stuff.

Can I fix this from my Storyboard with some attributes setting that I don't understand? Or do I need to add some methods to my subclasses? Or maybe I need to wrap my UITableViewController with some other kind of controller?

I've tried numerous variations of the ViewController Layout and Extend Edges settings in the Storyboard attributes page, but none of them seem to change it for the better.

Update: I think my problem is very similar to iOS 7: UITableView shows under status bar. The only difference, is that I'm embedded in a TabBarController, and that case is as the root view. I tried the solution listed there of embedding in a NavigationController and setting Show Navigation Bar to False, but it didn't make any difference.

Screen Shots:

My storyboard (shrunk) showing a tabbed controller, with 2 children, one single view, and the other the table view.

Storyboard

Settings for the tab bar controller

tab bar controller settings

Settings for the table view controller

table view controller settings

What the app ends up looking like on my phone

enter image description here

How the Story Ended

Despite lots of answers below, none of them really worked. Some kind of a little, but not really. I tried the Embed in NavigationController approach as well, and that also had issues. What did work though, was this:

  1. Add UIViewController
  2. Set child controller relationship with it and tab bar controller (just like the other two I already had)
  3. Add a TableView (not controller) to the new UIViewController, position as desired, it'll snap to the bottom of the status bar
  4. Set the TableView's delegate and tableSource as the new controller
  5. Create a custom UIViewController subclass and update the class type of the controller in the storyboard
  6. Copy the table related methods from my custom UITableViewController subclass to my new subclass
  7. Select my prototype table cell from the original, and command+drag it to the new table view
  8. Happily delete the original TableViewController (and wrapper NavigationController) too
  9. Update the tab bar item to match the previous
  10. Chock another one up for "you're trying to hard"
Community
  • 1
  • 1
Travis Griggs
  • 21,522
  • 19
  • 91
  • 167

13 Answers13

33

Try this in viewDidLoad:

self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);

20 px being the height of the status bar. If you have a navigation bar use 64 instead of 20

JustAnotherCoder
  • 2,565
  • 17
  • 38
  • 1
    Well, this is closest yet. It causes the initial layout to be what I'm looking for. When scrolling, it still underlaps though. I'm beginning to think that a UITableViewController is really not meant to exist without a UINavigationController around it? – Travis Griggs Dec 20 '13 at 21:56
  • replace 20 with 64. status bar + nav bar height = 64. hope this works – JustAnotherCoder Dec 21 '13 at 00:03
  • I misread your comment. The only other idea I have is to put a dummy UINavigationBar with a background image which is all transparent except for the portion behind the status bar – JustAnotherCoder Dec 21 '13 at 01:46
  • Please fix the spelling, should be tableView. Thanks. – RajV Feb 03 '14 at 18:54
  • This worked for me, only if placed inside viewDidLoad (i.e. not in viewWillAppear) and the 20 was actually -20 (negative). – Rob Sep 29 '15 at 18:50
15

In case anyone is still reading this thread:

What worked for me is to also uncheck the "Extend Edges" options in the parent tab bar controller. That gives a consistent behaviour in iOS7 as well as iOS6.

Florian
  • 159
  • 1
  • 3
6

I was having the same problem when using the SWRevealController.

Using the comments above and below I was able to get it to work by putting this in the

-(void)viewWillAppear instead of ViewDidLoad
     self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
reVerse
  • 35,075
  • 22
  • 89
  • 84
user3696154
  • 79
  • 1
  • 4
4

Have you tried adding something like this to the view controller's viewWillAppear method:

 if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
 {
    self.edgesForExtendedLayout = UIRectEdgeNone;
 }
holex
  • 23,961
  • 7
  • 62
  • 76
Robert
  • 5,278
  • 43
  • 65
  • 115
  • In the view controller's `viewWillAppear` method works for me. – Robert Dec 19 '13 at 16:49
  • I added that (didn't even bother with the if guard), didn't really change anything. :( – Travis Griggs Dec 19 '13 at 18:36
  • 1
    @TravisGriggs, if it is not working for you, you have implemented something seriously improperly, because that is the official way how that situation should be handled in an iOS7 app. – holex Dec 27 '13 at 02:19
  • 1
    @holex, did you make an app with the storyboard as pictured (or with an embedding NavigationController) and actually try it out on a real device? – Travis Griggs Dec 27 '13 at 02:25
  • @TravisGriggs, your question is a kind of joke, isn't it? – holex Dec 27 '13 at 02:26
  • I am having the same problem as @Travis Griggs. Have been beating my head against the wall for a day now. Gosh it's awfully nice to have an official way to handle things that doesn't friggin work. – c roald Mar 17 '14 at 21:12
2

In case anyone misses the How the story ended section at the end of the (now long) question, the short answer is: Use a simple UIViewController with a TableView, instead of a TableViewController if you want to achieve the stated goal.

Travis Griggs
  • 21,522
  • 19
  • 91
  • 167
  • 9
    So using static cells in this case would be impossible. – user623396 Apr 07 '14 at 09:04
  • @user623396 Yep, this won't work because a UITableViewController is required when using static cells. Bummer. – user3344977 Aug 13 '14 at 20:43
  • 1
    not ideal solution... can not work when using static cells :( – kolisko May 13 '16 at 18:00
  • I don't believe this changes anything. A UIViewController will have the same behavior. The only difference is that you can move the TableView as a workaround to not understanding how to place your view content directly below the navigation bar. Instead, I see two valid solutions: * One is to use `self.edgesForExtendedLayout = UIRectEdgeNone` as recommended by others. * Another is to use the navigation bar style to Opaque, which pushes the view content below the nav bar, since it would block the content underneath it. – Hugh Sep 14 '16 at 15:16
2

I added the following to viewWillAppear

self.tableView.contentInset = UIEdgeInsetsMake(22, 0, 0, 0);
Brian Broom
  • 497
  • 4
  • 11
2

You can also solve this through Storyboard.

Select the Table View from the Project Outline (left side of the editor) and then go to Properties (right side) > Size inspector tab > Scroll View > Content Insets > Top

Elsa
  • 153
  • 1
  • 6
2

suppose your table's @IBOutlet is

 @IBOutlet var tableView: UITableView!

create a function prepareTable(). add the below line into that method

tableView.contentInset.top = UIApplication.shared.statusBarFrame.height

call this method from ViewDidLoad()

Dilip Jangid
  • 754
  • 1
  • 10
  • 20
1

Looks like you just want to make the NavBar nonTranslucent, you could try using

[self.navigationController.navigationBar setTranslucent:NO];
Moxy
  • 4,162
  • 2
  • 30
  • 49
hv88
  • 328
  • 1
  • 7
  • I added `[self.navigationBar setTranslucent:NO];` to my `viewDidLoad` method on my `UITableViewController` subclass. Apparently, `UITableViewController`s don't have a `navigationBar` property; it doesn't compile. – Travis Griggs Dec 19 '13 at 18:39
  • try [self.navigationController.navigationBar setTranslucent:NO]; – hv88 Dec 19 '13 at 19:20
  • OK, that compiles. And I don't need the try. But it doesn't have the desired effect sadly :( – Travis Griggs Dec 19 '13 at 19:23
  • if possible, could u post a screenshot of what happens currently and what you are looking for. – hv88 Dec 19 '13 at 19:26
  • he is talking about the status bar, not the navigation bar. – Neva Mar 27 '14 at 14:56
  • Thanks a lot. When you have the UITableViewController within a navigation controller. Setting the nav bar to "not translucent" the status bar become "not tranluscent too" – LastMove Mar 21 '15 at 21:52
  • I don't get why this works but somehow it actually aligns the tableView below the status bar and if you have a navigation bar, with it as well. – Ace Green Sep 04 '15 at 21:42
1

I encountered the same problem and the solution that worked for me was to add a section header view:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

I then added 20 to the origin.y of my text on the header.

I then changed the header height by adding 20 to the original height using the

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return myHeight+20;
}
RYUX123
  • 191
  • 1
  • 6
1

For me an easy solution was (code is in C# that's because appears to be invalid)...

  1. Just in the UITableViewController constructor create a new UIView (set same dimension of the TableView).

  2. Add the TableView to the new created view.

  3. Set new created View to the UITableViewController's View property...

On the constructor of the UITableViewController

var view = new UIView ();
view.Frame = this.TableView.Frame;
view.AddSubview (this.TableView);

this.View = view;
Community
  • 1
  • 1
Ricardo LR
  • 58
  • 1
  • 7
1

As of iOS 8.4 I didn't get anywhere with the various storyboard options listed in other answers.

I worked around this without resorting to any dimensional constants by putting a regular view in my tab controller, then filling that with a "Container View" which I then connected to my UITableViewController with an "embed" segue.

My table now respects both my navigation bar and the tab bar at the bottom.

bitmusher
  • 877
  • 1
  • 7
  • 16
0

Let's say your Outline view, or Storyboard, is a Tab Bar Controller that currently has a Table View Controller. When you run the app, your table view cells are running under the status bar that seems to have a transparent background. This sucks!

If you spent hours trying everything you could find on StackOverflow to no avail, felt like maybe it really was time to consider a new career and were preparing to dial 1-800-LUV-TRUK or 1-800-SHT-KIKR, give yourself a pat on the back, open up whatever elixir you drink in times such as this, because it's not your fault. Really. Travis is absolutely right that no amount of code in viewDidLoad, viewWillAppear, or viewDidAppear or button selecting/deselecting in IB will help in this situation.

Travis' solution above will certainly work, but it's a bit long, there's copying and pasting of code, I have a short attention span such that an episode of Bugs Bunny feels like a full-length movie to me, so I just know that I'll screw-up anything that complicated. But, hey, your mileage may, nay likely will, vary. Anyhoo...

In Xcode 7.3 for an app running iOS 9 (I assume 7 and 8 but I don't know this for certain and am currently too lazy to check) there is an easier way that doesn't require one to write any code. And it's done all within Xcode's Interface Builder.

(Caveat: Sorry if any of the terms aren't accurate. Please let me know where I was mistaken and I'll correct any mislabeling.)

  1. Go to the Utilities area of Interface Builder and select the Object library from the library pane.

  2. Select a Navigation View Controller object and drag it into your Storyboard scene. You'll notice that two scene items appear while you're dragging–these are a Navigation Controller Scene and a Table View Controller Scene.

  3. Delete the duplicate Table View Controller Scene that came-along with your Navigation Controller Scene.

  4. Select the relationship connection between your Tab Bar Controller and your Table View Controller and hit "Delete".

  5. Reposition the Navigation Controller and your Table View Controller the way you want in your storyboard.

  6. Control-drag from your Tab Bar Controller Scene to the Navigation Controller Scene and select "Relationship Segue, view controller".

  7. Control-drag from your Navigation Controller Scene to your Table View Controller Scene and select "Relationship Segue, root view controller".

  8. Lastly, in the Utilities' Objects library, drag a Navigation Item object into your Table View Controller Scene's Table View.

Now when you run your app, you will have a navigation bar and your table view cells will no longer appear under a transparent status bar.

Hope this helps.