115

I have dragged a plain jane UITableView onto a UIViewController in iOS 7.

Now there is an vertical offset of space before the first cell starts. How do I get rid of it? I want the first line to be much closer to the top edge of where the UITableView actually starts. I did not ask for the large offset did I?

enter image description here

Any ideas?

MMiroslav
  • 1,672
  • 20
  • 32
user798719
  • 9,619
  • 25
  • 84
  • 123
  • 43
    I was helped by the following: YouStoryboard.storyboard > YouViewController > Attributes inspector > Uncheck - Adjust scroll view insets. – Alexander Oct 01 '13 at 13:20
  • 17
    btw, you can take screenshot of iOS Simulator using **Command key + S** – Hemang Dec 21 '13 at 09:06
  • @Alexander: I was also helped with your suggestions, however unchecking the ExtendEdges.UnderTopBars caused again the vertical offset space to appear. I'm not sure if its one of the (many?) bugs in Xcode6, but these issues give me quite some headaches once in a while! – iOS-Coder Feb 26 '15 at 10:50

21 Answers21

107

The new iOS 7 implementation of UIViewController has a new set of options that allows the developer to choose if the system will automatically add insets for UIScrollView, UITableView and derivations.

To disable this behaviour uncheck these boxes for all your wanted UIViewControllers in InterfaceBuilder, on UIViewController selected object inspector:

View Controller Inspector

For more details:

  1. Submit your iOS 7 apps today.
  2. iOS 7 UI Transition Guide > Appearance and Behavior
MultiColourPixel
  • 1,222
  • 10
  • 19
xudre
  • 2,731
  • 2
  • 19
  • 19
81

By default table view controllers will pad the content down under the nav bar so you could scroll the content under it and see it, in a blurred state, underneath the navbar/toolbar.

Looks like you're positioning it at 44 (maybe 64)px to move it out from under the nav bar, but it already compensates for this so you get a big gap.

Go to the storyboard/xib in IB and untick the show content under nav bar stuff.

Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
Cocoadelica
  • 3,006
  • 27
  • 30
68

From iOS7 transition guide:

If you don’t want a scroll view’s content insets to be automatically adjusted, set automaticallyAdjustsScrollViewInsets to NO. (The default value of automaticallyAdjustsScrollViewInsets is YES.)

   self.automaticallyAdjustsScrollViewInsets = NO;
sovanlandy
  • 1,700
  • 2
  • 19
  • 24
  • 9
    This can also be set in XCode on the attributes inspector. Uncheck the `Adjust Scroll View Insets` checkbox for the view controller layout. – Andrew Dec 27 '13 at 11:12
  • 1
    If you load the UIViewController programatically (without using a XIB) this one works like a charm. Set `automaticallyAdjustsScrollViewInsets = NO` in the view controller. – KabraBoja Feb 27 '14 at 16:16
  • This was it for me. Confusing because my TableView was inside a container view and initially appeared fine. But it got screwed up when popping back from another view controller. – n13 Jul 01 '15 at 01:59
  • Great! Save me a lot of time! – inix Apr 14 '16 at 12:49
34

i had a similar problem, after dismissing a viewController, the contentOffset from my tableView was changed to (0, -64).

my solution was a little weird, i tried all the other answers but had no success, the only thing that fixed my problem was to switch the tableView position in the controls tree of the .xib

it was the first control in the parent View like this:

before

I moved the tableView right after the ImageView and it worked:

after

it seems that putting the table view in the first position was causing the trouble, and moving the table view to another position fixed the problem.

P.D. I'm not using autoLayout neither storyboards

hope this can help someone!

Chuy47
  • 2,391
  • 1
  • 30
  • 29
  • I noticed the same thing! I don't put any additional views, but simple compensate the gap moving the UITableView -44 top. In IB it seems I have to move -64px, but in runtime -64px cause tablview overlay the navigation bar and -44px is OK. I can't quite explain it. I found this issue in iPad popover view, when I didn't notice any similar issue in iPhone storyboard. – Mike Keskinov Apr 30 '14 at 18:34
  • This problem arises even with the uiview. if the view shown in the user interface are placed not in the same order. – Rinku May 22 '14 at 04:56
  • 2
    I had the same issue today, with XCode 6.1. Chalk up another 2-3 hours wasted, trying to work around Apple's bugs... – Mike Gledhill Dec 11 '14 at 08:49
  • 3
    This was extremely helpful and deserves more attention! No amount of fiddling with view controller settings or content inset/offset helped, but changing the order of the views in the storyboard solved the problem for me. – Caleb Dec 24 '14 at 18:40
  • This just worked for me using a tableview in a uicontainerview – paynio Feb 25 '15 at 20:44
  • Works perfectly - the problematic view (for me it was a container view in which there is a UITableView) must NOT be the first in the order of views. – mllm May 17 '16 at 12:19
  • Genius! Thanks so much... this was driving me crazy! Just moving the UITableView from first position did the charm. – FrizzTheSnail Jul 16 '16 at 20:16
  • 1
    Apple, I mean... WTF? Thanks man, this also fixed storyboard with autolayout. – Borzh Jun 21 '17 at 19:36
30

it resolve my similar problem:

if ([[UIDevice currentDevice].systemVersion floatValue] >= 7){
tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);
}
Alex
  • 2,100
  • 19
  • 26
  • 1
    You should check fro the system version this way use: `if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) ` – rckoenes May 06 '14 at 14:00
  • This worked for me for the spacing issue I was having but now my pull-to-refresh control spinner shows up partially obscured & underneath my top menu. Anyone seen this also? Any workarounds? – Nick Aug 08 '14 at 09:23
  • @nickv2002 try create tableView programatically – Alex Aug 09 '14 at 06:25
  • I tried all the other solutions but only this one worked for me – DanielR May 25 '15 at 14:37
13

Try using this

tableView.separatorInset = UIEdgeInsetsZero;

Obviously, if you're supporting anything less than iOS7 you will need to ensure that the object responds to this selector before calling it.

David Attaie
  • 164
  • 4
  • 4
    not sure why this is being voted up... separatorInset just changes the distance lines between cells are inset from the edge of the view. The question is asking about the space above and below cells – Rembrandt Q. Einstein Jun 17 '14 at 15:34
  • The image is misleading, but a common google search for the margin problem yields this page. – Will Jun 26 '14 at 05:55
9

Seriously, changing contentOffset is not the solution. You're just patching a problem and not fixing the cause. I've been facing the same problem and it turns out that grouped tableViews have a padding on the top. In my case setting the type to plain has done the trick.

Hopefully it saves someone a few minutes. Z.

Zoltán
  • 1,422
  • 17
  • 22
8

With iOS 9, none of the other answers from this page worked for me (i.e. unchecking boxes in Storyboard, setting automaticallyAdjustsScrollViewInsets to NO).

My workaround I am really dissatisfied about was this:

- (void)viewDidAppear:(BOOL)animated {
    self.tableView.contentOffset = CGPointMake(0.0, 0.0);
    self.tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0);
}

The same lines in viewWillAppear or viewDidLoad were ineffective.

Mick F
  • 7,312
  • 6
  • 51
  • 98
  • This should be the only answer for uitableviewcontroller iOS 9.... really, nothing else helped, and i've tried them all, where did you find this on, or how did you figured it out? many 10x – Erez Jun 12 '16 at 20:26
  • Unchecking `Adjust Scroll View insets` checkbox works for iOS 9. – Adam Aug 10 '16 at 09:08
  • Adjust Scroll View insets not working for me any other solution ? – Yogesh Patel Jun 14 '19 at 14:01
5

Sometimes, I get a 64 height gap at the top of my Table View when the UIViewController is embedded inside a Navigation Controller.

enter image description here

In the past, I would just re-create everything, hoping that the constraints turn out correct after a clean slate.

TIL: If you don't want to make a vertical constraint to the Top Layout Guide, you can hold down the Option key to access the Container Margin.

enter image description here

Then make sure the Top Space to Superview constant is set to 0. This worked for me at least.

enter image description here

Robert Chen
  • 5,179
  • 3
  • 34
  • 21
4

THis works for me:

- (void)loadView
{
    [super loadView];

    [self setAutomaticallyAdjustsScrollViewInsets:YES];

    self.edgesForExtendedLayout = UIRectEdgeNone;
    self.view.frame = CGRectZero;
    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
Zack Brown
  • 5,990
  • 2
  • 41
  • 54
yeahdixon
  • 6,647
  • 1
  • 41
  • 43
2

If you add an empty UIView before UITableView (or any view is scrollable such as ScrollView and TextView), you can have a luck.

Capella
  • 881
  • 3
  • 19
  • 32
1

I had a UITableViewController embedded in a container view. To get rid of the unwanted 64 points of vertical space, I needed to uncheck the 'Adjust Scroll View Insets' in Interface Builder and set the UITableView's contentInset in my UITableViewController's viewWillAppear as below.

The size of the vertical space appears to match the navigation bar's frame height and y offset. The problem only occurred on iOS 7.

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

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
        const CGRect navBarFrame = self.navigationController.navigationBar.frame;
        const CGFloat blankVerticalSpace = navBarFrame.origin.y + navBarFrame.size.height;
        self.tableView.contentInset = UIEdgeInsetsMake(-blankVerticalSpace, 0, 0, 0);
    }
}
user2067021
  • 4,399
  • 37
  • 44
1

In Xamarin iOS, I had this issue occuring on a backgrounded UITableViewController just after the foreground modal dialog was being dismissed. In the process of moving into the foreground, the UITableViewController had insets set (somewhere by iOS):

This class solved it

public class UITableViewControllerWithBugFix : UITableViewController {
    public UITableViewControllerWithBugFix(UITableViewStyle withStyle) : base(withStyle) {
    }

    public override void ViewWillLayoutSubviews() {
        if (TableView.ContentInset.Top != 0.0f)
            TableView.ContentInset = UIEdgeInsets.Zero;
        if (TableView.ScrollIndicatorInsets.Top != 0.0f)
            TableView.ScrollIndicatorInsets = UIEdgeInsets.Zero;

        base.ViewWillLayoutSubviews();
    }
}
Herman Schoenfeld
  • 8,464
  • 4
  • 38
  • 49
1

From time to time I get back to this awful situation, and I notice that it's still quite unknown. So, for future memory...

Lately, I'm fixing with this workaround.

  1. Add a subview at the top of the UITableView, with zero pixel height. Works with Autolayout or without.
  2. If I feel confident :-) I remove this fake view, fix the constraints on the top, and magically it works.

Don't ask me why, I still think it's a bug deep in UIKit.

klauslanza
  • 671
  • 1
  • 6
  • 8
0

If you go to storyboard, you can change the offset by selecting the table and under the Table View section in the Attributes inspector you just change the Separator Insets on the left to 0.

0

I think the real solution is to set up your top and bottom constraints on the tableview be equal to the topMargin and bottomMargin. Not the top layout guide and bottom layout guide. This allows you to keep automaticallyAdjustsScrollViewInsets to be true.

Dan
  • 191
  • 1
  • 7
0

Swift 3 solution:

class PaddingLessTableView : UITableView
{
    override func headerView(forSection section: Int) -> UITableViewHeaderFooterView?
    {
        return nil
    }

    override func footerView(forSection section: Int) -> UITableViewHeaderFooterView?
    {
        return nil
    }
}
hhamm
  • 1,511
  • 15
  • 22
0

If you embedded your TableViewController in a NavigationController or a ContainerView, You have to constraint to margins instead of top Layout guide in Storyboard. Check constraint to margins when you are doing the constraints No other way worked for me. I couldn't comment so I'm just reiterating on Robert Chens answer.

user3296487
  • 326
  • 2
  • 12
0

I tried several of the answers. Changing the settings in storyboard caused ripple problems with an overlay menu that pops in from the left.

I only have a blank UIViewController in storyboard, otherwise everything is programmatically generated.

I have same problem with a UITableView inside a UIView inside a UIViewController. Namely, the section headers start too far down when the UIViewController is embedded in a Navigation Controller. W/o the navigation controller everything works fine.

To fix the problem I created a UILabel and with constraints placed the UILabel bottom constraint = the top constraint of the UIView (so it does not show on the screen. Now with that additional control (the new Label) the TableView behaves properly.

    inputsContainerView.addSubview(titleLabel)
    inputsContainerView.addSubview(tableView)

    // inputsContainerView
    ///////////////////////////////////////
    inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
    inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -40).isActive = true
    inputsContainerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.7).isActive = true

    // tableView
    ///////////////////////////////////////
    tableView.centerXAnchor.constraint(equalTo: inputsContainerView.centerXAnchor).isActive = true
    tableView.topAnchor.constraint(equalTo: inputsContainerView.topAnchor).isActive = true
    tableView.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
    tableView.heightAnchor.constraint(equalTo: inputsContainerView.heightAnchor).isActive = true

    // titleLabel - inserted to stop bad section header behavior
    ///////////////////////////////////////
    titleLabel.centerXAnchor.constraint(equalTo: inputsContainerView.centerXAnchor).isActive = true
    titleLabel.bottomAnchor.constraint(equalTo: inputsContainerView.topAnchor).isActive = true
    titleLabel.widthAnchor.constraint(equalTo: inputsContainerView.widthAnchor).isActive = true
    titleLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
john
  • 505
  • 1
  • 7
  • 15
0

I had a same problem in iOS 11 and xib, UITableviewController and I solved it as below

[self.tableView setContentInset:UIEdgeInsetsMake(-44,0,0,0)];
dobiho
  • 1,025
  • 1
  • 11
  • 22
0

If none of the above answers work, try changing the table view style to plain from grouped

enter image description here

iOS_nerd
  • 9
  • 2
  • then maybe there won't be any need to adjust the content offset or make navigation controller related changes – iOS_nerd Jan 18 '22 at 12:22