31
votes

I have a custom tableViewController that I'm adding to a TabBarController with

self.tabBarController.viewControllers = [NSArray arrayWithObjects:someOtherViewController, customTableViewController, nil];
self.tabBarController.selectedIndex = 1;

The issue I'm having is that the last 1.5 tableViewCells are being covered by the tab bar at the bottom of the screen on an iPhone 4 running iOS7. When I use the iOS Simulator - iPhone Retina (4-inch) / iOS 7.0 the issue still exists.

What is the correct way to make the tableView line up with the top of the tabBar at the bottom of the screen without using 'magic numbers'?

10
i suggest you that create View-controller subclass of UIViewcontroller and add Tableview IBOutlate. via xib or storyBoard and add That created viewController into tabbar controllerNitin Gohel
That's exactly the setup right nowJuJoDi

10 Answers

77
votes

Try this for your CustomViewController:

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIEdgeInsets adjustForTabbarInsets = UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.tabBarController.tabBar.frame), 0);
    self.scrollView.contentInset = adjustForTabbarInsets;
    self.scrollView.scrollIndicatorInsets = adjustForTabbarInsets;
}
51
votes

It's an iOS 8 solution but it may work on iOS 7 to: Go to storyboard > select table view controller > uncheck "Under Bottom Bars". That's it!

example

7
votes

Setting the contentInset of your table view with a .bottom value of 49 points should correct this.

Under the right configurations, setting YES for the new UIViewController property on iOS 7 called automaticallyAdjustsScrollViewInsets should correct this, but (again) it depends upon a lot of other factors (view hierarchy, parent view controller's settings, et cetera).

6
votes

The accepted answer doesn't quite work for me--my set up is a little different. I'm programatically creating my view controllers. My app's root is a tab bar controller, one tab is a navigation controller, whose root is a UIViewController with a table view as the main view.

What works for me though is when I manually computed the table view's height and set it in the frame when alloc-initing the table view. The general formula is:

screen height - (status bar height + nav bar height + tab bar height)

5
votes
CGFloat bottom =  self.tabBarController.tabBar.frame.size.height;
NSLog(@"%f",bottom);
[self.tableview setScrollIndicatorInsets:UIEdgeInsetsMake(0, 0, bottom, 0)];
self.tableview.contentInset = UIEdgeInsetsMake(0, 0, bottom, 0);
2
votes

Embed your table controller in a navigation controller. 1. select the view in story board. 2. On menu bar select Editor -> embed in -> navigation controller.

Hope that helps

1
votes

I have a similar view hierarchy to Matt Quiros: UITabBarController -> UINavigationController -> UIViewController -> UITableViewController (embedded as a subview of the UIViewController). The other answers didn't work in my case, and I had to set the table view's frame manually in the table view controller's viewWillAppear: method.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Adjust height of tableview (does not resize correctly in iOS 7)
    CGRect tableViewFrame = self.tableView.frame;
    tableViewFrame.size.height = [self heightForTableView];
    self.tableView.frame = tableViewFrame;
}

- (CGFloat)heightForTableView
{
    return CGRectGetHeight([[UIScreen mainScreen] bounds]) -
           (CGRectGetHeight([[UIApplication sharedApplication] statusBarFrame]) +
            CGRectGetHeight(self.navigationController.navigationBar.frame) +
            CGRectGetHeight(self.tabBarController.tabBar.frame));
}

If anyone finds a better solution, please share!

0
votes

I think this would work better for you:

After [super viewDidLoad];

try the following code:

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;
0
votes

You can also implement viewDidLayoutSubviews and use bottomLayoutGuide to get the height of the tab bar:

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    CGFloat bottomOffset = self.bottomLayoutGuide.length;

    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, bottomOffset, 0);
}
0
votes

Even though changing the contentInset of your table View is a working solution, I find it better to make sure your table view stops before the Tabbar.

As Paul Newman said, using the bottomLayoutGuide is a good thing, specially if you are using autolayout. In My case adding a constraint to the bottom of the tableview linking to the top of the BottomLayoutGuide was a clean solution, this is an example with Storyboard, but it can be done in code as well.

enter image description here

Hope it helps.