38

This question should not be mixed up with this here.. These are two different things.

There is a good example how to use a UITableView Header on SO.

This all works fine and the main header is fixed on top as long as the style is set to plain.

But if I use sections, the main header no longer sticks to top and moves away while scrolling to the bottom.

In this method, I am returning the header for each section.

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

In this method I am setting the height for the header section above:

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

In this method, I am setting the real table header.

- (void)viewWillAppear:(BOOL)animated {
    ...
    self.recordTableView.tableHeaderView = headerView;
}

Is it even possible having a fixed table header, while using sections? What is an alternative solution to this please?

Community
  • 1
  • 1
Houman
  • 64,245
  • 87
  • 278
  • 460
  • Possible duplicate of [UITableView with fixed section headers](http://stackoverflow.com/questions/17582818/uitableview-with-fixed-section-headers) – Iulian Onofrei Oct 04 '16 at 12:50
  • As the OP stated in his opening sentence, it is not the same question. – ghr Jul 03 '17 at 00:59
  • Take a look at https://stackoverflow.com/questions/16590099/uitableview-header-without-bouncing-when-pull-down – ghr Jul 04 '17 at 03:56

4 Answers4

65

If you want a UITableViewController (static cells/keyboard handling) and have a fixed header then you should use Containment. You can do this from a Storyboard by setting up a UIViewController with your fixed header and then using a Container View to embed the UITableViewController.

Storyboard object for Container View

Once you have your containing view setup, you right-click drag from the Container View to the View Controller you want to embed - the UITableViewController in this case.

enter image description here

You can access and get a reference to the contained View Controller (the UITableViewController) from the Container View Controller by implementing the prepareForSegue:sender: method.

Joony
  • 4,498
  • 2
  • 30
  • 39
  • You don't need a container view for this. You can simply add the table to the view controller directly but of course not full-screen. Create your static view just above the table. – C6Silver May 09 '17 at 17:16
  • 3
    @C6Silver UITableViewController can be nicer that just a regular UIViewController with a UITableView, as I stated at the start of my answer (static cells/keyboard handling). – Joony May 09 '17 at 19:23
  • @Joony Very fair based on your parenthetical. – C6Silver May 09 '17 at 20:46
  • this is certainly the best approach however one issue is if you plan to use refreshControl and a searchController added to the navigationItem then when you pull to refresh, the tableView content will move down but the fixed header will not and be covered by the rubber banding navigationBar. so if a searchBar is needed best to add as the tableView.tableHeaderView until this is sorted. – alionthego Jan 11 '18 at 15:18
34

There’s no way to maintain the header of a tableView fixed, but an useful approach when you need a unique header, is to use a UIViewController rather than a UITableViewController, and set the header (UIView) out from the tableView.

Something like this:

enter image description here

Matteo Gobbi
  • 17,697
  • 3
  • 27
  • 41
  • :) nothing works in any conditions. You have to decide which is the way to take in order to reach what you want. Static cells are not a problem, you can avoid to use if you need instead a static view above your tableView, otherwise there would not be reason to have an object called UITableViewController, and one UITableView insertable in another view. – Matteo Gobbi Mar 18 '15 at 12:11
  • 1
    @Alon_T you can include static table view as emdedded vc – k06a May 27 '15 at 08:11
  • But this is not a good solution especially when you have tabbar items on bottom, and the tableview has limited view and when you want to scroll down the tableview, you might want the top navigation bar to scroll to top to make it out of the view and the header will stick to the top view. Taking out the header from tableview will make you very hard to achieve this result. – felixwcf Aug 23 '16 at 08:34
  • This is fine. Exept, you should make the table view full screen and then adjust the content inset and scroll indicator insets. –  Jul 26 '17 at 12:01
  • If you use `UIViewController`, then you lose the automatic keyboard handling provided by `UITableViewController` – Abhishek Bedi Sep 11 '17 at 15:28
4

If you want to keep the class as a UITableViewController you can add your header as a subview to the tableview's superview. You will have to also push the tableview top inset down so your headerview doesnt hide the table.

Here is a sample code to put inside your tableViewController subclass (This example assumes your tableview controller is inside a navigation controller, so it pushes the view to below the navigation bar):

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.automaticallyAdjustsScrollViewInsets = NO;

}

-(void)addHeaderView{
    CGFloat yPosition = self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height;
    mainHeaderView = [[UIView alloc] init];

    const CGFloat mainHeaderHeight = 44;
    [mainHeaderView setFrame:CGRectMake(0, yPosition, self.view.frame.size.width, mainHeaderHeight)];

    mainHeaderView.backgroundColor = [UIColor redColor];

    [self.tableView.superview addSubview:mainHeaderView];
    [self.tableView setContentInset:UIEdgeInsetsMake(yPosition + mainHeaderHeight, self.tableView.contentInset.left, self.tableView.contentInset.bottom, self.tableView.contentInset.right)];
 }
amirfl
  • 1,634
  • 2
  • 18
  • 34
2

I haven't done this, but the first thing I would think to try is to place my tableview in a UIView and make my own header there in that UIView. Seems a trivial matter to make that view appear to be the header of the table and it would certainly stay put.

Dean Davids
  • 4,174
  • 2
  • 30
  • 44