9

Is it just me or they added a lot more padding to section headers and footers of grouped UITableViews in iOS 11?

I compiled my app to run with iOS 11 and noticed the extra padding. I kinda solved it by setting contentInset.top to a negative value checking if the os is iOS 11, but this is a ugly workaround.

Is there any other better way do clear the extra padding of grouped table views in order to achieve the same results across all supported iOS? It kinda stinks to have multiple checks for such a silly thing.

Screenshot for comparison:

iOS 10 vs iOS 11 UITableView comparison

As you can see, on iOS 11 there's extra spacing between sections (yeah, those are sections!).

Phillip
  • 4,276
  • 7
  • 42
  • 74
  • 6
    Personally, I think that as long as you are using the native SDK's UI frameworks (UIKit), you should accept most visual desing idiosincracies (i.e., metrics decisions) of the OS **as they are**, instead of trying to force a unified look across all OS versions. After all, the user expects a consistent look among different apps running on the same OS (yours and other developer's), **not** among instances of the same app running on different OS versions. Sticking to recommended practices (as opposed to hacky workarounds) also has a lower chance of inadvertently breaking down the line. – Nicolas Miari Sep 21 '17 at 08:55
  • 1
    That's absolutely true. My only concern regarded users who weren't able to see and reach certain features or certain cells due to the increased padding of the tableView on iOS 11. Other than that, I really love UIKit and I'm getting the most out of it. – Phillip Sep 21 '17 at 09:01
  • 1
    I haven't played very much with iOS 11 / Xcode9 yet (I _am_ using existing apps on my iPhone, though), but I feel like a screenshot could _really_ improve your question :-) – Nicolas Miari Sep 21 '17 at 09:03
  • Haha, you're right! Question updated with screenshot :) – Phillip Sep 21 '17 at 09:28
  • Now it is much clearer what you are asking; you make a very unorthodox use of grouped table views indeed. If those rows where normal UIView instances, you could easily accomplish it with autolayout. But `UITableView` is a scroll view, so it accepts clipping as a normal thing... – Nicolas Miari Sep 21 '17 at 09:31
  • That's just an example of what I meant, but I'm a little lost on your "if those rows were normal UIView instances", what do you mean by that? Also, I'm using autolayout everywhere since I create all views by code :) – Phillip Sep 21 '17 at 09:35
  • By the way, you can set the section header height with the `UITableViewDelegate` method `tableView(_:heightForHeaderInSection:)`. Just make sure to pass `.leastNormalMagnitude` instead of zero... https://stackoverflow.com/a/45938287/433373 – Nicolas Miari Sep 21 '17 at 09:35
  • I meant that, if you had a normal, non-scrolling `UIView` containing three UIViews (one for each row) instead of a `UITableView` with `UITableViewCells`, you could achieve your desired layout with autolayout constraints on the storyboard. Thats what I meant :) – Nicolas Miari Sep 21 '17 at 09:37
  • 1
    Oh I see, that makes sense indeed! I needed it to push another tableView, that's why I used it. By the way that was just an example, I have other tableViews affected by this "padding drama", and the funny thing is that the height was already set to .leastNormalMagnitude! – Phillip Sep 21 '17 at 09:40
  • 1
    In that case, Im out of ideas! – Nicolas Miari Sep 21 '17 at 09:41
  • Thanks for the help anyway! – Phillip Sep 21 '17 at 09:41
  • Thank for your help @Nicolas Miari – Bkillnest Sep 25 '17 at 09:53
  • Check the Header Height and Footer Height of table view in Sections in Size Inspector on the right side of storyboard. – Nithin Michael Oct 24 '17 at 15:19

7 Answers7

13

This is new contentInsetAdjustmentBehavior parameter of UIScrollView which you can set it as .never to prevent extra padding

if #available(iOS 11.0, *) {
    tableView.contentInsetAdjustmentBehavior = .never
}

or in storyboard under Size Inspector

enter image description here

Rashid
  • 1,515
  • 16
  • 16
  • This seems to work but, if you have a navigation bar in the view, it is cut off by that. How would we solve that issue? – Simon Mar 28 '18 at 18:47
  • @Simon what do you mean “navigation bar” in the view? Can you provide details? – Rashid Mar 28 '18 at 18:52
  • @Rashid I've embedded my tableview inside a UINavigationController. so it has a navigation bar on top of the tableview. When setting the `tableView.contentInsetAdjustmentBehavior = .never` it brings it all the way to top under the navigation bar – Simon Mar 28 '18 at 18:54
  • @Simon Do you face same problem in the question when it is set to .automatic ? – Rashid Mar 28 '18 at 19:01
  • Yes i have the same problem – Simon Mar 28 '18 at 19:19
4

In iOS 11 the section footer has a view that adds to the spacing between the sections. You would need to set the view of the footer to nil explicitly in addition to adjusting the height for the footer:

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
    return nil;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    return 0.1;
}

This will make your table view to look like what you had in iOS 10 and would also not have any effect on previous versions of iOS. You can do the same for the header if you don't need the headers.

Bms270
  • 1,586
  • 15
  • 18
2

You just need to set the table view's header and footer view.

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return [[UIView alloc] init];
}
- (UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    return [[UIView alloc] init];
}
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
wangjx
  • 21
  • 1
  • Yes, this solution works in iOS 11, no need to tableView.contentInsetAdjustmentBehavior = .never. Also, note that in iOS 11 zero values in heightForFooterInSection and heightForHeaderInSection started to work and lead to really zero height of the header and/or footer. – mkll Apr 07 '18 at 00:51
0

I had a similar problem I think it was a bug in the Old Xcode.

If you are using autolayout and you have Content View and views inside this, Constrain to margins didn't work in Xcode 8, now fixed in xCode 9. You have to go in redo your constraints and uncheck the box on the View inside all table view cells. This will then be consistent on all ios 10 and ios 11 devices.

enter image description here

HannahCarney
  • 3,441
  • 2
  • 26
  • 32
0

I solved my problem by setting the header and footer height in Storyboard. Apparently, in Xcode 9 these are the default values when you create a UITableView

enter image description here

I tried to set them to 0, but 1 is the minimum and that solved the problem. Also, I checked how it behaves if the automatic is checked and it works as well.

Also, I don't know is it a bug or something, but I couldn't do it on existing table. I needed to delete it and drag it to UIViewController again.

Đorđe Nilović
  • 3,600
  • 1
  • 25
  • 20
0

If rashid's answer didn't work with setting the contentInsetAdjustmentBehavior to never then try the following:

self.tableView.estimatedRowHeight = 0;
self.tableView.estimatedSectionHeaderHeight = 0
self.tableView.estimatedSectionFooterHeight = 0

iOS 11 Floating TableView Header

luxo
  • 378
  • 1
  • 4
  • 11
0

With my .grouped UITableView I was facing the same issue in iOS 11, it worked fine when I was using a UITableViewController, but not in UIViewController, following worked in my case:

tableView.estimatedSectionHeaderHeight = 0

Without above line tableView(heightForHeaderInSection never gets called.

It seems like a bug in iOS 11.

AamirR
  • 11,672
  • 4
  • 59
  • 73