Ios UITableViewHeader与IB的互动

Ios UITableViewHeader与IB的互动,ios,uitableview,interface-builder,Ios,Uitableview,Interface Builder,多年来,我一直避免像瘟疫一样使用界面构建器,因此我决定给它一个机会。这不容易 以UITableViewHeaderFooterView为例。与UITableViewCell类似,它有一个contentView属性。与UITableViewCell不同,它在Interface Builder对象库中没有模板 我们应该如何使用Interface Builder创建一个包含contentView内容的UITableViewHeaderFooterView?registerNib:forHeaderFo

多年来,我一直避免像瘟疫一样使用界面构建器,因此我决定给它一个机会。这不容易

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


我们应该如何使用Interface Builder创建一个包含
contentView
内容的
UITableViewHeaderFooterView
registerNib:forHeaderFooterViewReuseIdentifier:
的存在让我觉得这应该是可能的。

这是我用IB:

a。创建一个子类(
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文件来实现这一点:

  • 创建名为CustomFooterView.xib的空NIB文件
  • 在Interface Builder中编辑NIB文件,并将最顶层的UIView自定义类更改为UITableViewHeaderFooterView
  • 禁用NIB中的自动布局
  • UITableViewHeaderFooterView
    view的背景色设置为默认值
  • 使视图自由且大小正确(例如320 x 44)
  • 在UITableViewController
    viewDidLoad
    中,注册要与重用标识符一起使用的NIB文件:

    [self.tableView registerNib:[UINib nibWithNibName:@"CustomFooterView" bundle:nil] forHeaderFooterViewReuseIdentifier:@"Footer"];
    
  • 在UITableViewController的
    表视图:ViewForFooterInstitution:
    中,使用页脚标识符获取并返回视图:

    - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
    {
        if (section == 2)
            return [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Footer"];
    
        return nil; 
    }
    
  • 我找到了更简单的方法

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

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


    就是这样。

    只需使用IB中的UITableViewCell模板。将类更改为UITableViewHeaderFooterView。给你。。。使用contentView。

    我想出了一个可怕的办法,就是在headerFooter类中创建一个IBMoutlet contentView,并将其连接到xib中的“内容视图”(将xib像tableViewCell一样布置,view->contentView->mystuff)

    你会得到警告,好的,准备好攻击


    删除IBOutlet,它将全部工作

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

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

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

  • 我创建了一个xib,其视图仅扩展UIView,而不是UITableViewHeaderFooter
  • 在viewDidLoad中,我注册了内置的UITableViewHeaderFooter类

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

  • 在我的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 = "..."
    
  • 这似乎有效,利用了重用,并且不会产生任何警告


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

  • 创建一个新类,该类将UIView(“AwesomeHeaderView”)作为子类,并创建您的Outlet:

    class AwesomeHeaderView: UIView {
        @IBOutlet var myCustomLabel: UILabel!
    }
    
  • 创建一个具有ui视图的XIB文件(“MyNewHeader.XIB”),如下所示 父视图。将父UIView的类类型更改为新创建的自定义类(“AwesomeHeaderView”)。根据需要,添加任何其他视图作为其子视图和链接出口等(注意:为了确保视图符合新的可读内容指南,我选中所有对象上的“保留Superview边距”和“跟随可读宽度”框)
  • 在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
    }
    

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

  • 创建一个(新文件/CocoaTouchClass)UITableViewHeaderFooterView .h.m.xib正常情况下

  • 暂时将超类从UITableViewHeaderFooterView重命名为UIView。拖动并根据需要将UI项分配给代码,IB将分配键值 正确地说,完成后返回UITableViewHeaderFooterView

  • 在tableview中,使用registernb:注册,而不是使用registerClass:。正常准备tableview的其余部分(即:出列)
    效果很好,不过我还得做两件事才能让它发挥作用:1。禁用NIB的自动布局。2.将NIB中的
    UITableViewHeaderFooterView
    视图的背景色设置为“默认”。谢谢@Frederik,我基于此更新了答案。我认为这是更好的解决方案,因为您可以连接此xib中的插座,在另一个解决方案中,你不能这样做。这个解决方案对我来说是一个更干净的解决方案。与使用tableview单元格作为标题相比,这个解决方案工作得非常好,更干净。
    contentViewSize
    是{0,0,0,0}这实际上是不必要的,苹果公司有一些示例代码来证明这一点。将这个问题与新来者联系起来是一个来自过去的爆炸-你可以使用con