UITableViewHeaderFooterView with IB



在多年避免像瘟疫一样避免使用界面生成器之后,我决定给它一个机会。这并不容易。

UITableViewHeaderFooterView为例。像UITableViewCell一样,它有一个contentView属性。与UITableViewCell不同,它在界面生成器对象库中没有模板。

我们应该如何使用界面生成器创建一个包含contentView内内容的UITableViewHeaderFooterViewregisterNib:forHeaderFooterViewReuseIdentifier:存在的事实使我认为这应该以某种方式成为可能。

这是我

最接近用 IB 定义UITableViewHeaderFooterView

a. 创建一个UITableViewHeaderFooterView子类 ( MYTableViewHeaderFooterView (。

b. 仅为contentView创建 nib 文件 ( MYTableViewHeaderFooterContentView (。

c. 覆盖MYTableViewHeaderFooterView中的initWithReuseIdentifier:以加载 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. 在界面生成器中编辑 NIB 文件,并将最顶层的 UIView 自定义类更改为 UITableViewHeaderFooterView。
  3. 禁用 NIB 中的自动布局
  4. 将视图的背景色设置为UITableViewHeaderFooterView默认
  5. 使视图自由格式并正确调整大小(例如 320 x 44(。
  6. 在UITableViewController中viewDidLoad注册要与重用标识符一起使用的NIB文件:

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

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

只需在 IB 中使用 UITableViewCell 模板即可。 将类更改为 UITableViewHeaderFooterView。在这里你有它...与内容视图。

我找到了更简单的方法。

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

2(在您的头文件中将超类从UITableViewCell更改为UITableViewHeaderFooterView

就是这样。

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

  1. 创建一个子类UIView("AwesomeHeaderView"(的新类并创建您的出口:

    class AwesomeHeaderView: UIView {
        @IBOutlet var myCustomLabel: UILabel!
    }
    
  2. 创建一个 XIB 文件 ("MyNewHeader.xib"( 的 UIView 为父视图。将父 UIView 的类类型更改为新创建的自定义类("AwesomeHeaderView"(。根据需要,添加任何其他视图,因为它是子视图和链接插座等(注意:为了确保视图符合新的可读内容指南,我选中了所有对象的"保留超级视图边距"和"遵循可读宽度"框(。
  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
    }
    

我还遇到了上面的弃用警告和无法设置背景颜色等。最终,我发现根据苹果的文档,

在大多数情况下,您可以按原样使用 [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.h.m.xib 正常

  2. 暂时将超类从UITableViewHeaderFooterView重命名为UIView。根据需要将UI项拖拽分配给代码,IB将分配键值正确,完成后恢复为 UITableViewHeaderFooterView。

  3. 在表视图中,使用 registerNib: 进行注册,而不是 registerClass:。 正常准备表视图的其余部分(即:取消排队(。
我想

出的一个可怕的技巧是创建一个IBOutlet contentView ih你的headerFooter类,并将其连接到xib中的"内容视图"(让你的xib像tableViewCell一样布局,View->contentView->mystuff(。

你会收到警告,好的,准备好黑客攻击了...

删除IBOutlet,它将全部工作。

我发现的最好的方法:

  1. 创建 HeaderFooterView(.h/.m(,例如 header
  2. 创建一个 xib(视图(,名称相同
  3. 使根视图类成为您的类( header (
  4. [重要] 将所有插座连接到根视图,而不是File's Owner

最后,将您的笔尖注册到桌子(全部完成(。

最新更新