简体   繁体   中英

iPhone UITableView with a header area

I have a view that was created with all of the default UITableView stuff, but now I need to add a header area above where the UITableView is (so the UITableView will scroll normally, but the top 100px of the screen or so will have static header content). I don't see where I can resize the UITableView in IB, and am not sure how to do this.

Does anyone know?

You can use UITableViewDelegate methods to create a custom header view for a table and specify the height, namely tableView:viewForHeaderInSection: and tableView:heightForHeaderInSection: . You can add whatever you like to the view. Here's an example that adds a right aligned UILabel :

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

    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width,30)];

    UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 0, headerView.frame.size.width-120.0, headerView.frame.size.height)];

    headerLabel.textAlignment = NSTextAlignmentRight;
    headerLabel.text = [titleArray objectAtIndex:section];
    headerLabel.backgroundColor = [UIColor clearColor];

    [headerView addSubview:headerLabel];

    return headerView;

}

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

    return  30.0;
}

Why don't you use the UITableView provided header?. As follow:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section

{
     return @"My Title";
}

Additionally you may resize your table view in IB by dragging the borders.

When you add a UIView or one of its subclasses onto the UITableView using IB (just drag a UIView and drop it onto the UPPER part of UITableView of yours), it automatically adds that UIView component and makes it the "tableHeader" component.

Each UITableView has one tableHeader and one tableFooter component reserved...

This way the new view would be a part of the UITable, and scroll with it or appear/disappear or whatever you do to the table. You can change its hidden property if you need conditional behavior.

On the other hand, if you want the header view stay put, as the table scrolls, then it is better to make the table smaller and put the header above it as suggested in other answers...

I finally solved this problem the right way without changing the base class. The one answer to add the view to the parent nav controller is nice but the transitions look horrible.

The fix is actually easy. The trick is to create custom setter and getter for self.tableView property. Then, in loadView, you replace the view with a fresh UIView and add the tableView to it. Then you're free to add subviews around the tableView. Here's how it's done:

In header:

@interface CustomTableViewController : UITableViewController
{
    UITableView *tableView;
} 

In .m:

- (UITableView*)tableView
{
    return tableView;
}

- (void)setTableView:(UITableView *)newTableView
{
    if ( newTableView != tableView )
    {
        [tableView release];
        tableView = [newTableView retain];
    }        
}

- (void)loadView {
    [super loadView];
    //save current tableview, then replace view with a regular uiview
    self.tableView = (UITableView*)self.view;
    self.view = [[UIView alloc] initWithFrame:self.tableView.frame];
    [self.view addSubview:self.tableView];    

    //code below adds some custom stuff above the table
    UIView *customHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)];
    customHeader.backgroundColor = [UIColor redColor];
    [self.view addSubview:customHeader];
    [customHeader release];

    self.tableView.frame = CGRectMake(0, customHeader.frame.size.height, self.view.frame.size.width, self.view.frame.size.height - customHeader.frame.size.height);
}

- (void)viewDidUnload
{
    self.tableView = nil;
    [super viewDidUnload];
}

Enjoy!

You will have to embed the UITableView in a UIView alongwith another view (which you are referring to as header section).

So, the UIView will have 2 subviews. The header view followed by the table view.

  • UIView (parent)
    • UIView (header)
    • UITableView (table)

Hope this helps.

I like the answer from noodl_es (upvoted), because it provides the functionality and behavior you want, yet you don't have to worry about resizing the UITableView: that is handled for you automatically. However, the solution is best suitable only if the header information pertains specifically to the first section of the table (or if the table has only one section). If the table has more than one section, then the header of the second section will push away the header of the first section when scrolled up, and therefore the header view will not appear to pertain to the whole table.

Suppose to have your UITableViewController

@interface MXMTableViewController : UITableViewController <UITableViewDelegate,UIScrollViewDelegate> {
/// your table view interface here
}

and a xib with you simple UITableView defined yet in it, you can do as Mihir says overriding the loadView method like this:

- (void)loadView {

    [super loadView];

    UIView *mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];

    self.view = mainView;

    [mainView release];

    // Add Header View
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 36)];
    headerView.backgroundColor = [UIColor redColor];
    [self.view addSubview:headerView];

    // now, move your table view down. Check you nib to choose 
    // the right Y-axis offset
    CGRect f = tableView.frame;
    f.origin.y += headerView.frame.size.height/2;
    tableView.frame = f;

    // Add the table view to the container view
    [self.view addSubview:self.tableView];

    // Add footer
    UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, self.tableView.frame.size.height, 320, 125)];
    footerView.backgroundColor = [UIColor redColor];
    [self.view addSubview:footerView];
    [footerView release];

    [headerView release];

}

...and that's it. You have a UITableView with fixed header and footer.

PS. You may now use your xib custom views as the header and footer's views.

Found a solution at iphonedevsdk

Instead of doing this:

[tableViewController.view addSubview:viewSubclass];

do this

[tableViewController.navigationController.view addSubview:viewSubclass];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM