UITableViewHeaderFooterView with IB

2019-02-01 07:28发布

After many years of avoiding Interface Builder like the plague I decided to give it a chance. It's not easy.

Take UITableViewHeaderFooterView for example. Like UITableViewCell, it has a contentView property. Unlike UITableViewCell, it doesn't have a template in the Interface Builder object library.

How are we supposed to use Interface Builder to create a UITableViewHeaderFooterView with the content inside contentView? The fact that registerNib:forHeaderFooterViewReuseIdentifier: exists makes me think this should be possible somehow.

8条回答
2楼-- · 2019-02-01 07:59

I just did this with a footer and a NIB file:

  1. Create an empty NIB file with name CustomFooterView.xib.
  2. Edit the NIB file in the Interface Builder and change the topmost UIView custom class to UITableViewHeaderFooterView.
  3. Disable Auto Layout in the NIB.
  4. Set the background color of UITableViewHeaderFooterView view to Default.
  5. Make the view freeform and correct size (for example 320 x 44).
  6. In your UITableViewController viewDidLoad register the NIB file to be used with a reuse identifier:

    [self.tableView registerNib:[UINib nibWithNibName:@"CustomFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"Footer"];
    
  7. In your UITableViewController's tableView:viewForFooterInSection: use the Footer identifier to fetch and return the view:

    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
    {
        if (section == 2)
            return [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"];
    
        return nil; 
    }
    
查看更多
贪生不怕死
3楼-- · 2019-02-01 08:01

I found easier way.

1) Create subclass of UITableViewCell and set your xib file

2) In your header file change superclass from UITableViewCell to UITableViewHeaderFooterView

That's it.

查看更多
来,给爷笑一个
4楼-- · 2019-02-01 08:03

This is the closest I got to define a UITableViewHeaderFooterView with IB:

a. Create a UITableViewHeaderFooterView subclass (MYTableViewHeaderFooterView).

b. Create a nib file for the contentView only (MYTableViewHeaderFooterContentView).

c. Override initWithReuseIdentifier: in MYTableViewHeaderFooterView to load the view defined in the nib file.

 - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithReuseIdentifier:reuseIdentifier];
    if (self)
    {
        NSArray* objects = [[NSBundle mainBundle] loadNibNamed:@"MYTableViewHeaderFooterView"
                                                          owner:self
                                                        options:nil];
        UIView *nibView = [objects firstObject];
        UIView *contentView = self.contentView;
        CGSize contentViewSize = contentView.frame.size;
        nibView.frame = CGRectMake(0, 0, contentViewSize.width, contentViewSize.height);
        [contentView addSubview:nibView];
    }
    return self;
}

d. Register the MYTableViewHeaderFooterView class instead of the nib file:

[self.tableView registerClass:[MYTableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"cell"];
查看更多
叼着烟拽天下
5楼-- · 2019-02-01 08:07

Just use the UITableViewCell template in IB. Change the class to UITableViewHeaderFooterView. Here you have it... with a contentView.

查看更多
孤傲高冷的网名
6楼-- · 2019-02-01 08:10

This solution works well, especially if you want it to work correctly in relation to Readable Content Guides (introduced in iOS 9). Instead of creating a UITableViewHeaderFooterView, it simply returns a custom UIView (from a XIB) when it is required:

  1. Create a new class that subclasses UIView ("AwesomeHeaderView") and create your outlets:

    class AwesomeHeaderView: UIView {
        @IBOutlet var myCustomLabel: UILabel!
    }
    
  2. Create a XIB file ("MyNewHeader.xib") with a UIView as the parent view. Change the parent UIView's class type to your newly created custom class ("AwesomeHeaderView"). As required, add any additional views as it's children and link outlets etc. (NB: To ensure views comply to the new Readable Content Guides I check the boxes "Preserve Superview Margins" and "Follow Readable Width" on all objects).
  3. In your UIViewController (or UITableViewController) call the following:

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        guard let headerView = NSBundle.mainBundle().loadNibNamed("MyNewHeader", owner: nil, options: nil).first as? AwesomeHeaderView else {
            return nil
        }
    
        // configure header as normal
        headerView.backgroundColor = UIColor.redColor()
        headerView.myCustomLabel.textColor = UIColor.whiteColor()
        headerView.myCustomLabel.text = "Hello"
    
        return header
    }
    
查看更多
Evening l夕情丶
7楼-- · 2019-02-01 08:24

An awful hack I figured out is to create a IBOutlet contentView ih your headerFooter class and hook it up to the your "content view" in the xib (Have your xib laid out like a tableViewCell, View->contentView->mystuff).

You'll get warnings, ok ready for the hack...

Delete the IBOutlet and it will all work.

查看更多
登录 后发表回答