【问题标题】:UITableViewHeaderFooterView in InterfaceBuilder界面生成器中的 UITableViewHeaderFooterView
【发布时间】:2013-07-15 10:18:25
【问题描述】:

我想使用 IB 在单独的 .xib 中创建自定义标题部分视图

但是在 IB 中我找不到组件 UITableViewHeaderFooterView(类似于 UITableViewCell)并为其分配重用

那么如何在自定义页眉部分创建呢?

我创建了一个继承自 UITableViewHeaderFooterView 的类 MySection 创建一个 .xib,MySection.xib 注册 xib 以便单元格重用

问题是,如何使用 initWitReuseIdentifier....

【问题讨论】:

    标签: cocoa-touch uitableview


    【解决方案1】:

    绝对有可能,Apple 提供了一个示例 here

    下载示例代码并查看SectionHeaderView.xib。

    这样做的方法是创建一个带有单个 UIView 的 xib。然后,将类类型设置为继承自 UITableViewHeaderFooterView 的类。

    一旦你有一个继承自 UITableViewHeaderFooterView 的类的 nib,调用以下代码来注册该类以作为页眉或页脚重用:

    static NSString * const SectionHeaderViewIdentifier = @"SectionHeaderViewIdentifier";
    
    [self.tableView registerNib:[UINib nibWithNibName:@"SectionHeaderView" bundle:nil] forHeaderFooterViewReuseIdentifier:SectionHeaderViewIdentifier];
    

    要使用视图,请实现表委托方法 tableView:viewForHeaderInSection: 如下:

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSinteger)section {
    
        SectionHeaderViewClass *sectionHeaderView = (SectionHeaderView *)[tableView dequeueReusableHeaderFooterViewWithIdentifier:SectionHeaderViewIdentifier];
    
        // Do stuff...
    
        return sectionHeaderView;
    }
    

    【讨论】:

    • 在 iOS8 上会有这样的警告: Setting the background color on UITableViewHeaderFooterView has been deprecated。请改用 contentView.backgroundColor。要修复,在 IB 中,将 UIView 的背景颜色设置为“默认”。
    • 在 iOS 8.3 中,您还需要将 UITableView 的 sectionHeaderHeight 属性设置为某个值,否则它默认为 0,并且不会调用您的委托方法。 (是的,这很愚蠢。)
    • 澄清 OP(因为我花了一段时间):您的 XIB 应该有 一个 根级子视图(类似于 UITableViewCell 的内容视图)和所有您的其他视图应该是它的子视图。除了上面@patr1ck 的评论之外,似乎在iOS 10.x 中您必须同时设置tableView.sectionHeaderHeight tableView.estimatedSectionHeaderHeight(即使您覆盖了UITableViewDelegate 中各个部分的值。 )
    • 这个问题是你的页眉/页脚视图的子视图不会最终成为 contentView 的子视图,它们应该在哪里——而是直接添加到 UITableViewHeaderFooterView 本身。
    • @smileyborg 有没有办法通过Interface Builder 将子视图添加到UITableViewHeaderFooterViewcontentView
    【解决方案2】:

    我写了一个guide(在 iOS 9 上测试),包括 4 个步骤:

    1. 子类UITableViewHeaderFooterView
    2. 使用子类视图创建 Nib,并在页眉/页脚中添加 1 个包含所有其他视图的容器视图
    3. viewDidLoad 中,调用registerNib:forHeaderFooterViewReuseIdentifier: 获取表格视图
    4. 实现viewForHeaderInSection 并使用dequeueReusableHeaderFooterViewWithIdentifier 取回页眉/页脚

    【讨论】:

    • 我想知道为什么这不适用于 Interface Builder 中的视图。它不会在视图上实例化我的 UILabel。我尝试将它嵌套在容器视图中。它们都包含在自定义 UITableViewHeaderFooterView 子类中。
    • 如何在 UITableViewHeaderFooterView 中赋予按钮操作??
    • @AndrewKirna 页脚视图中的内容不可见或正在加载。只显示空的灰色条,甚至没有改变背景颜色。没有得到什么是错的。
    • 嗨@iPhone7。我只是决定回复,因为我还有一部 iPhone 7...jk 但那是我的手机?我在上面评论是因为我也没有让它工作。从那以后,我一直在用 Swift 设计我所有的自定义 UITableViewHeaderFooterViews。然后我在表格中注册课程并使用dequeueReusableHeaderFooterView(withIdentifier:) 应用它们。希望有帮助!
    【解决方案3】:

    虽然所有这些答案都有效,但它们并没有完全解决如何使用 Interface Builder 设置 reuseIdentifier 的原始问题。确实,在“用户定义的运行时属性”的帮助下是可能的。您可以使用属性直接在 Interface Builder 中设置reuseIdentifier

    这样做将完成与 UITableViewCell Interface Builder 属性检查器中的原生 reuseIdentifier 字段完全相同的事情。

    【讨论】:

    • 好像是个bug。因为从技术上讲,应该有一个字段来添加标识符,因为您可以在 Table View 中将 Header View 出列。
    【解决方案4】:

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

    1. 创建一个(新建文件/CocoaTouchClass) UITableViewHeaderFooterView .h.m.xib 正常

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

    3. 在您的表格视图中,使用 registerNib: 代替 registerClass: 进行注册。正常准备其余的tableview(即:dequeue)。

    【讨论】:

      【解决方案5】:

      在 IB 中创建视图并分配其类就足够了(无需在界面构建器中设置重用标识符(如通过自定义 UITableViewCell))

      【讨论】:

        【解决方案6】:

        从 iOS 8 开始,UITableHeaderFooterView 的子视图应该在容器视图中并且您不应该在页眉/页脚视图上设置背景。对象库缺少 UITableHeaderFooterView,所以我尝试了在 xib 中创建一个 UIView 并将另一个作为容器视图添加到其中的方法。我担心的是 UITableHeaderFooterView 上没有内容视图出口,我不能确定我的内容视图实际上最终是内容视图。

        这听起来像是 hack 或 API 误用,但我没有遇到任何警告或问题:

        1. 创建 UITableHeaderFooterView 的子类
        2. 为其创建一个空的xib
        3. 从对象库中拖动一个 UITableViewCell
        4. 将 UITableHeaderFooterView 的类分配给该单元格
        5. 分配重用标识符

        我想知道这种方法的任何(潜在)问题,请发表评论。

        【讨论】:

        • 我无法将UITableHeaderFooterView 类分配给单元格。 Xcode 不接受它。
        【解决方案7】:

        UITableViewHeaderFooterView 文档包含registerNib:forHeaderFooterViewReuseIdentifier: 方法

        但目前(截至 2013 年 9 月 4 日)Interface Builder 中的对象库不包含 UITableViewHeaderFooterView。 这使得 registerNib:forHeaderFooterViewReuseIdentifier: 无用,因为无法在 nib 中正确配置视图。 也许最好尝试重用单元格...

        【讨论】:

          【解决方案8】:
          1. 在 xib 中创建新视图

          2. 从 nib 加载视图并设置为作为页脚视图到 tableview 的视图

          UIView *headerview = [[[NSBundle mainBundle] loadNibNamed:@"ReguistrationHeaderView" owner:self options:nil] firstObject]; [self.tableview setTableFooterView:headerview];

          【讨论】:

            【解决方案9】:

            我总是使用 UITableViewCell 作为我的表的页眉(或页脚),以便能够直接在情节提要中编辑它们。

            我的工作流程:

            • 我创建了一个 MyHeaderTableViewCell 类继承 UITableViewCell 并添加了我需要的所有插座
            • 我将 UITableViewCell 添加到故事板中的表格中
            • 我给它一个重用标识符(es:“HeaderCell”)
            • 我将单元格出列并将其内容用作我的标题

            关键部分是返回 headerCell 的 contentView (而不是 headerCell 本身),否则在使用 reloadRowsAt 或类似函数时会遇到奇怪的行为(最多消失标题)。

            这是我的代码:

            func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            
                let headerCell = tableView.dequeueReusableCell(withIdentifier: "HeaderCell") as! MyHeaderTableViewCell
            
                headerCell.lblTitle.text = "My Title"
            
                return headerCell.contentView }
            

            这样做我从来没有遇到过问题(或者至少我的客户总是付钱给我)。

            【讨论】:

            • 你写你从来没有遇到过任何问题,但它看起来像一个冒险的方法和API的滥用
            • @PeterLapisu 感谢您的回复。我同意你的观点,这可能是有风险的,并且是对 API 的相当滥用,但只要它没有任何大的缺点,我发现它是干净代码和易用性之间的一个很好的权衡。所以这只是一个解决方案,我同意你的观点,不是最干净的。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-11-09
            • 1970-01-01
            • 2011-07-19
            • 1970-01-01
            • 1970-01-01
            • 2014-05-20
            • 2011-03-26
            相关资源
            最近更新 更多