带IB的UITableViewHeaderFooterView

经过多年避免瘟疫之类的Interface Builder,我决定给它一个机会。 这并不容易。

UITableViewHeaderFooterView为例。 与UITableViewCell一样,它有一个contentView属性。 与UITableViewCell不同,它在Interface Builder对象库中没有模板。

我们如何使用Interface Builder创建一个带有contentView内容的UITableViewHeaderFooterViewregisterNib:forHeaderFooterViewReuseIdentifier: exists的事实让我觉得这应该是可能的。

这是我用IB定义UITableViewHeaderFooterView的最接近的:

一个。 创建一个UITableViewHeaderFooterView子类( MYTableViewHeaderFooterView )。

湾 仅为contentView创建一个nib文件( MYTableViewHeaderFooterContentView )。

C。 覆盖initWithReuseIdentifier:MYTableViewHeaderFooterView中加载nib文件中定义的视图。

  - (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。 注册MYTableViewHeaderFooterView类而不是nib文件:

 [self.tableView registerClass:[MYTableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:@"cell"]; 

我只是用页脚和NIB文件做到这一点:

  1. 创建一个名为CustomFooterView.xib的空NIB文件。
  2. 在Interface Builder中编辑NIB文件,并将最顶层的UIView自定义类更改为UITableViewHeaderFooterView。
  3. 禁用NIB中的自动布局
  4. UITableViewHeaderFooterView视图的背景颜色设置为Default
  5. 使视图自由forms和正确的大小(例如320 x 44)。
  6. 在您的UITableViewController viewDidLoad注册要与重用标识符一起使用的NIB文件:

     [self.tableView registerNib:[UINib nibWithNibName:@"CustomFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"Footer"]; 
  7. 在你的UITableViewController的tableView:viewForFooterInSection:使用Footer标识符来获取并返回视图:

     - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { if (section == 2) return [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"]; return nil; } 

只需在IB中使用UITableViewCell模板即可。 将类更改为UITableViewHeaderFooterView 。 在这里你有…带有contentView。

我发现更简单的方法。

1)创建UITableViewCell的子类并设置您的xib文件

2)在头文件中将超类从UITableViewCell更改为UITableViewHeaderFooterView

而已。

此解决方案运行良好,特别是如果您希望它与可读内容指南(在iOS 9中引入)相关的正常工作。 它不是创建UITableViewHeaderFooterView,而是在需要时返回自定义UIView(来自XIB):

  1. 创建一个子类UIView(“AwesomeHeaderView”)并创建出口的新类:

     class AwesomeHeaderView: UIView { @IBOutlet var myCustomLabel: UILabel! } 
  2. 使用UIView作为父视图创建XIB文件(“MyNewHeader.xib”)。 将父UIView的类类型更改为新创建的自定义类(“AwesomeHeaderView”)。 根据需要,添加任何其他视图,因为它的子项和链接出口等。(注意:为确保视图符合新的可读内容指南,请选中所有对象上的“保留Superview边距”和“跟随可读宽度”框)。
  3. 在您的UIViewController(或UITableViewController)中调用以下内容:

     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 } 

我也经历过上面的弃用警告和无法设置背景颜色等。最后,我发现根据Apple的文档,

在大多数情况下,您可以按原样使用[UITableViewHeaderFooter]类,而不进行子类化。 如果要显示自定义内容,请创建内容的子视图,并将其添加到contentView属性中的视图。

根据该建议,我采取了以下步骤:

  1. 我创建了一个xib,其视图只扩展了UIView – 而不是UITableViewHeaderFooter。
  2. 在viewDidLoad中,我注册了内置的UITableViewHeaderFooter类

    tableView.registerClass(UITableViewHeaderFooterView.self,forHeaderFooterViewReuseIdentifier:“sectionHeader”)

  3. 在我的UITableViewController的viewForHeaderInSection委托中,我通过该标识符将标题视图出列,并检查标题视图是否已包含子视图。 如果没有,我加载我的xib并添加它。 然后我根据需要设置我的文本。

     override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let header = self.tableView.dequeueReusableHeaderFooterViewWithIdentifier("sectionHeader")! if header.contentView.subviews.count == 0 { header.contentView.addSubview(loadMyNib()) } let myView = header.contentView.subviews[0] as! MyView myView.label.text = "..." 

这似乎有效,利用重用,并且不会产生任何警告。

https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UITableViewHeaderFooterView_class/index.html#//apple_ref/occ/instm/UITableViewHeaderFooterView/prepareForReuse

以下变通方法使我能够将IB项目拖动到代码作为变量。 UITableViewHeaderFooterView不允许开箱即用。

  1. 通常创建一个(New File / CocoaTouchClass) UITableViewHeaderFooterView .hmxib

  2. 暂时 UITableViewHeaderFooterView中的超类重命名为UIView。 拖动 – 根据需要将UI项目分配给代码,IB将正确分配键值,完成后还原为UITableViewHeaderFooterView。

  3. 在你的tableview中,使用registerNib:来注册而不是registerClass : . 通常准备其余的tableview(即:dequeue)。

我想到的一个糟糕的黑客是创建一个IBOutlet contentView你的headerFooter类并将其连接到xib中的“内容视图”(让你的xib布局像tableViewCell,View-> contentView-> mystuff)。

你会得到警告,准备好了黑客……

删除IBOutlet,它将全部工作。