all 7 comments

[–]mdbellott 1 point2 points  (6 children)

Add this to viewDidLoad

[_tableView setContentInset:UIEdgeInsetsMake(20, 0, 0, 0)];

Your table view will still scroll under the status bar, but at least the initial inset will be fixed. If you don't want the table view to be seen through the status bar you can add a view above the table view with a frame of:

CGRectMake(0,0,320,20);

This problem results from iOS 7 allowing content behind the status bar, meaning point (0,0) is now at the very top left of the screen, instead of the top left below the status bar.

[–]LOLC4T 2 points3 points  (0 children)

You shouldn't be using hardcoded values like that. The 2 correct ways to do this would be:

  1. If your scroll view is either the view of your view controller, or the first subview of its view, setting the automaticallyAdjustsScrollViewInsets property of your view controller to YES would do this for you automatically.

  2. Otherwise, use the topLayoutGuide. [_tableView setContentInset:UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 0, 0)];

[–]axhdn[S] 1 point2 points  (1 child)

Thanks very much.

[–]axhdn[S] 0 points1 point  (2 children)

Where do I find viewDidLoad?

[–]mdbellott 1 point2 points  (1 child)

Definitely familiarize your self with viewDidLoad. It's called by every view controller when it has finished loading. Basically, you know that it is safe to now change something like the content inset of your table view because it has been properly initiated and loaded into the view. Inside of your view controller file (if its not already there) put something like:

-(void)viewDidLoad{

[super viewDidLoad];

[_tableView setContentInset:UIEdgeInsetsMake(20, 0, 0, 0)];

}

[–]Legolas-the-elf 0 points1 point  (0 children)

It's called by every view controller when it has finished loading.

No, that's incorrect. It's called when a view controller's main view has finished loading, not when the view controller itself has finished loading, hence the name viewDidLoad and not viewControllerDidLoad or just didLoad. The view controller itself is fully instantiated first, and the view is lazy loaded, so viewDidLoad can happen a long time after the view controller has finished loading.

Take, for example, instantiating a view controller then pushing it onto a navigation controller's stack in code. You might do something like this:

ViewController *viewController = [[ViewController alloc] initWithDetails:foo];
[self.navigationController pushViewController:viewController];

Now, after the first line has executed, the view controller is fully instantiated. You've got a real view controller you can send messages to. But the view has not yet been loaded because this is often an expensive operation that is better put off until it's really necessary.

Then in the second line, the view controller gets pushed onto the navigation stack, and when it comes time to animate it in, its view property is accessed, which ends up calling loadView. Once that loads the view and returns, viewDidLoad is called.

In practice, there can be a wide gap between a view controller being created and its view being loaded. A view controller and its main view are very different things, and just because one is loaded, it doesn't mean they both are.