如何使用UITableViewHeaderFooterView?

您好我想在我的应用程序中使用UITableHeaderFooterView,我这样做:

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. [_tableView registerClass:[M3CTableViewCell class] forCellReuseIdentifier:@"cell"]; [_tableView registerClass:[M3CHeaderFooter class] forHeaderFooterViewReuseIdentifier:@"footer"]; } - (UITableViewHeaderFooterView *)footerViewForSection:(NSInteger)section { M3CHeaderFooter * footer = [[M3CHeaderFooter alloc]initWithReuseIdentifier:@"footer"]; footer.textLabel.text = @"Test"; return footer; } 

通过这样做,我在Footer的地方没有得到任何东西。 而这个方法甚至没有被调用,但我认为这个方法是UITableViewDelegate协议的一部分。 请帮忙!!

使用可重复使用的页眉/页脚视图的新的iOS 6function涉及两个步骤。 你似乎只做了第一步。

第一步:通过注册UITableViewHeaderFooterView(我假设你的M3CHeaderFooter是UITableViewHeaderFooterView的子类)的自定义子类,告诉表视图什么类用于节标题视图。

第二步:通过实现tableView委托方法,告诉表视图使用(AND重用)标题部分的视图

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

所以在你的viewDidLoad中你可以实现如下的东西:

  // ****** Do Step One ****** [_tableView registerClass:[M3CHeaderFooter class] forHeaderFooterViewReuseIdentifier:@"TableViewSectionHeaderViewIdentifier"]; 

然后,在您创build并显示表视图的类中实现表视图委托方法:

 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 40.0; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { static NSString *headerReuseIdentifier = @"TableViewSectionHeaderViewIdentifier"; // ****** Do Step Two ********* M3CHeaderFooter *sectionHeaderView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier]; // Display specific header title sectionHeaderView.textLabel.text = @"specific title"; return sectionHeaderView; } 

现在请注意,您不需要inheritanceUITableViewHeaderFooterView即可使用它。 在iOS 6之前,如果您想要为某个部分创build一个标题视图,则需要实现上述tableView委托方法,并告诉表视图每个部分使用哪个视图。 所以每个部分都有你提供的UIView的不同实例。 这意味着如果你的tableView有100个部分,并且在委托方法中你创build了一个UIView的新实例,那么你应该为显示的100个部分头部提供tableView 100 UIViews。

使用可重复使用的页眉/页脚视图的新function,可以创build一个UITableViewHeaderFooterView的实例,系统将为每个显示的页眉重新使用它。

如果你想有一个可重用的UITableViewHeaderFooterView没有子类,那么你只需将你的viewDidLoad更改为:

 // Register the class for a header view reuse. [_buttomTableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"TableViewSectionHeaderViewIdentifier"]; 

然后你的委托方法如下:

 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 40.0; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { static NSString *headerReuseIdentifier = @"TableViewSectionHeaderViewIdentifier"; // Reuse the instance that was created in viewDidLoad, or make a new one if not enough. UITableViewHeaderFooterView *sectionHeaderView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:headerReuseIdentifier]; sectionHeaderView.textLabel.text = @"Non subclassed header"; return sectionHeaderView; } 

我希望这是清楚的。

编辑:当子类化标题视图,如果你想添加一个自定义视图到headerView你可以实现类似于以下代码:

  // Add any optional custom views of your own UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 50.0, 30.0)]; [customView setBackgroundColor:[UIColor blueColor]]; [sectionHeaderView.contentView addSubview:customView]; 

在子类中执行此操作,而不是viewForHeaderInSection:delegate方法(如Matthias所述),将确保只创build任何子视图的一个实例。 然后,您可以在子类中添加任何可以访问自定义子视图的属性。

UITableViewHeaderFooterView是我会编程处理视图,而不是使用故事板或XIB的less数地方之一。 既然你不能正式使用外观代理,并没有IB方式来做到这一点,而不会滥用UITableViewCells。 我以老式的方式来做,只要使用标签上的标签来获取自定义元素。

 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:kSectionHeaderReuseIdentifier]; if (headerView == nil) { [tableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:kSectionHeaderReuseIdentifier]; headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:kSectionHeaderReuseIdentifier]; } UILabel *titleLabel = (UILabel *)[headerView.contentView viewWithTag:1]; if (titleLabel == nil) { UIColor *backgroundColor = [UIColor blackColor]; headerView.contentView.backgroundColor = backgroundColor; titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 0.0f, 300.0f, 44.0f)]; titleLabel.textColor = [UIColor whiteColor]; titleLabel.backgroundColor = backgroundColor; titleLabel.shadowOffset = CGSizeMake(0.0f, 0.0f); titleLabel.tag = 1; titleLabel.font = [UIFont systemFontOfSize:24.0f]; [headerView.contentView addSubview:titleLabel]; } NSString *sectionTitle = [self.sections objectAtIndex:section]; if (sectionTitle == nil) { sectionTitle = @"Missing Title"; } titleLabel.text = sectionTitle; return headerView; } 

这是一个老post,有很好的答案,但我想分享一个解决我遇到的非常类似的问题。

起初,我用:

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

用我的标题视图的自定义原型单元格。 inheritanceUITableViewCell

  static NSString *cellIdentifier = @"CustomHeaderCell"; CustomHeaderCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 

但是,当animation表单标题上方的TableView单元格(使它们两倍高)标题视图将消失。 正如所指出的那样,这是因为实现只提供了一个视图,而不是一个可重用的视图。

我没有使用自定义的原型单元格放弃所有的东西,而是实现了UITableViewHeaderFooterWithIdentifier,并将其设置为原型单元格的contentView,而不用创buildUITableViewHeaderFooterWithIdentifier的子类。

  static NSString *customHeaderViewIdentifier = @"CustomHeaderView"; UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:customHeaderViewIdentifier]; headerView = (UITableViewHeaderFooterView *)cell.contentView; 

我意识到这会创build两个头视图的实例(至less我认为它会..),但它确实允许您保持自定义的原型单元格的好处,而不是以编程方式做所有事情。

完整代码:

  // viewDidLoad [myTableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"CustomHeaderView"]; // Implement your custom header -(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { static NSString *cellIdentifier = @"CustomHeaderCell"; CustomHeaderCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; static NSString *customHeaderViewIdentifier = @"CustomHeaderView"; UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:customHeaderViewIdentifier]; // do your cell-specific code here // eg. cell.myCustomLabel.text = @"my custom text" headerView = (UITableViewHeaderFooterView *)cell.contentView; return headerView; } 

有几种方法可以解决这个问题,但这里有一个Swift解决scheme:这里的想法是我们有一个名为SNStockPickerTableHeaderViewUITableViewHeaderFooterView的子类; 它公开了一个名为configureTextLabel()的方法,它在调用时设置文本标签的字体和颜色。 我们只有在标题被设置之后调用这个方法,那就是从willDisplayHeaderView ,并且字体被正确设置。

标题视图还支持一个自定义行分隔符,以便将其与其余单元格分开。

 // MARK: UITableViewDelegate func tableView(tableView:UITableView, willDisplayHeaderView view:UIView, forSection section:Int) { if let headerView:SNStockPickerTableHeaderView = view as? SNStockPickerTableHeaderView { headerView.configureTextLabel() } } func tableView(tableView:UITableView, viewForHeaderInSection section:Int) -> UIView? { var headerView:SNStockPickerTableHeaderView? = tableView.dequeueReusableHeaderFooterViewWithIdentifier(kSNStockPickerTableHeaderViewReuseIdentifier) as? SNStockPickerTableHeaderView if (headerView == nil) { // Here we get to customize the section, pass in background color, text // color, line separator color, etc. headerView = SNStockPickerTableHeaderView(backgroundColor:backgroundColor, textColor:primaryTextColor, lineSeparatorColor:primaryTextColor) } return headerView! } 

这里是自定义的UITableViewHeaderFooterView

 import Foundation import UIKit private let kSNStockPickerTableHeaderViewLineSeparatorHeight:CGFloat = 0.5 private let kSNStockPickerTableHeaderViewTitleFont = UIFont(name:"HelveticaNeue-Light", size:12) let kSNStockPickerTableHeaderViewReuseIdentifier:String = "stock_picker_table_view_header_reuse_identifier" class SNStockPickerTableHeaderView: UITableViewHeaderFooterView { private var lineSeparatorView:UIView? private var textColor:UIColor? required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } // We must implement this, since the designated init of the parent class // calls this by default! override init(frame:CGRect) { super.init(frame:frame) } init(backgroundColor:UIColor, textColor:UIColor, lineSeparatorColor:UIColor) { super.init(reuseIdentifier:kSNStockPickerTableHeaderViewReuseIdentifier) contentView.backgroundColor = backgroundColor self.textColor = textColor addLineSeparator(textColor) } // MARK: Layout override func layoutSubviews() { super.layoutSubviews() let lineSeparatorViewY = CGRectGetHeight(self.bounds) - kSNStockPickerTableHeaderViewLineSeparatorHeight lineSeparatorView!.frame = CGRectMake(0, lineSeparatorViewY, CGRectGetWidth(self.bounds), kSNStockPickerTableHeaderViewLineSeparatorHeight) } // MARK: Public API func configureTextLabel() { textLabel.textColor = textColor textLabel.font = kSNStockPickerTableHeaderViewTitleFont } // MARK: Private func addLineSeparator(lineSeparatorColor:UIColor) { lineSeparatorView = UIView(frame:CGRectZero) lineSeparatorView!.backgroundColor = lineSeparatorColor contentView.addSubview(lineSeparatorView!) } } 

这是结果,请参阅“热门股票”部分标题:

在这里输入图像说明

我不能在Cameron Lowell Palmer发表评论,但要回答Christopher King,有一个简单的方法来确保重用,而不需要对UITableViewHeaderFooterView进行子分类,但仍然使用自定义的子视图。

首先,不要注册类的头部视图重用。

然后在tableView:viewForHeaderInSection:你只需要在需要的时候创buildUITableViewHeaderFooterView:

 -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { static NSString *kYourTableViewReusableHeaderIdentifier = @"ID"; UILabel *titleLabel = nil; UITableViewHeaderFooterView *headerView = [tableView dequeueReusableHeaderFooterViewWithIdentifier:kYourTableViewReusableHeaderIdentifier]; if (headerView == nil) { headerView = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:kYourTableViewReusableHeaderIdentifier]; titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(...)]; titleLabel.tag = 1; // ... setup titleLabel [headerView.contentView addSubview:titleLabel]; } else { // headerView is REUSED titleLabel = (UILabel *)[headerView.contentView viewWithTag:1]; } NSString *sectionTitle = (...); // Fetch value for current section if (sectionTitle == nil) { sectionTitle = @"Missing Title"; } titleLabel.text = sectionTitle; return headerView; } 

这是一个“快速和肮脏”的方式来实现这一目标。 它会在标题中创build一个小的蓝色标签。 我已经证实,这在iOS 6和iOS 7中呈现OK。

在你的UITableViewDelegate中:

  -(void)viewDidLoad { ... [self.table registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"Header"]; ... } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 34.; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { UITableViewHeaderFooterView *header = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Header"]; UILabel *leftlabel = [[UILabel alloc] initWithFrame:CGRectMake(0., 0., 400., 34.)]; [leftlabel setBackgroundColor:[UIColor blueColor]]; [header.contentView addSubview:leftlabel]; return header; } 

如果在上面的全面答案中有所遗漏,那么人们可能会丢失的东西(与标准的cellForRowAtIndexPath:方法相比)就是您必须注册用于节标题的类。

 [tableView registerClass:[UITableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"SectionHeader"]; 

尝试添加registerClass:forHeaderFooterViewReuseIdentifier:并查看它是否开始工作。

方法可能不被称为的原因之一是桌子的样式。 标准vs分组处理页眉/页脚不同。 这也许可以解释为什么它没有被调用。

  1. 设置UITableView实例的delegate属性来引用实现下一个方法的控制器:

  2. 返回段脚注视图的方法:

    请求代表查看对象以显示在表视图的指定部分的页脚中。 - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

  3. 章节页脚的高度:

    要求代表的高度用于特定部分的页脚。

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