界面生成器中的 UITableViewHeaderFooterView
Posted
技术标签:
【中文标题】界面生成器中的 UITableViewHeaderFooterView【英文标题】:UITableViewHeaderFooterView in InterfaceBuilder 【发布时间】:2013-07-15 10:18:25 【问题描述】:我想使用 IB 在单独的 .xib 中创建自定义标题部分视图
但是在 IB 中我找不到组件 UITableViewHeaderFooterView(类似于 UITableViewCell)并为其分配重用
那么如何在自定义页眉部分创建呢?
我创建了一个继承自 UITableViewHeaderFooterView 的类 MySection 创建一个 .xib,MySection.xib 注册 xib 以便单元格重用
问题是,如何使用 initWitReuseIdentifier....
【问题讨论】:
【参考方案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 将子视图添加到UITableViewHeaderFooterView
的contentView
?【参考方案2】:
我写了一个guide(在 iOS 9 上测试),包括 4 个步骤:
-
子类
UITableViewHeaderFooterView
使用子类视图创建 Nib,并在页眉/页脚中添加 1 个包含所有其他视图的容器视图
在viewDidLoad
中,调用registerNib:forHeaderFooterViewReuseIdentifier:
获取表格视图
实现viewForHeaderInSection
并使用dequeueReusableHeaderFooterViewWithIdentifier
取回页眉/页脚
【讨论】:
我想知道为什么这不适用于 Interface Builder 中的视图。它不会在视图上实例化我的 UILabel。我尝试将它嵌套在容器视图中。它们都包含在自定义 UITableViewHeaderFooterView 子类中。 如何在 UITableViewHeaderFooterView 中赋予按钮操作?? @AndrewKirna 页脚视图中的内容不可见或正在加载。只显示空的灰色条,甚至没有改变背景颜色。没有得到什么是错的。 嗨@iPhone7。我只是决定回复,因为我还有一部 iPhone 7...jk 但那是我的手机?我在上面评论是因为我也没有让它工作。从那以后,我一直在用 Swift 设计我所有的自定义UITableViewHeaderFooterView
s。然后我在表格中注册课程并使用dequeueReusableHeaderFooterView(withIdentifier:)
应用它们。希望有帮助!【参考方案3】:
虽然所有这些答案都有效,但它们并没有完全解决如何使用 Interface Builder 设置 reuseIdentifier
的原始问题。确实,在“用户定义的运行时属性”的帮助下是可能的。您可以使用属性直接在 Interface Builder 中设置reuseIdentifier
:
这样做将完成与 UITableViewCell
Interface Builder 属性检查器中的原生 reuseIdentifier
字段完全相同的事情。
【讨论】:
好像是个bug。因为从技术上讲,应该有一个字段来添加标识符,因为您可以在Table View
中将 Header View
出列。【参考方案4】:
以下解决方法使我能够将 IB 项拖放到代码中作为变量。 UITableViewHeaderFooterView 不允许开箱即用。
创建一个(新建文件/CocoaTouchClass) UITableViewHeaderFooterView .h.m.xib 正常
暂时重命名超类从 UITableViewHeaderFooterView 到 UIView。根据需要将您的 UI 项拖放到代码中,IB 将分配键值 正确,完成后恢复为 UITableViewHeaderFooterView。
在您的表格视图中,使用 registerNib: 代替 registerClass: 进行注册。正常准备其余的tableview(即:dequeue)。【讨论】:
【参考方案5】:在 IB 中创建视图并分配其类就足够了(无需在界面构建器中设置重用标识符(如通过自定义 UITableViewCell))
【讨论】:
【参考方案6】:从 iOS 8 开始,UITableHeaderFooterView 的子视图应该在容器视图中并且您不应该在页眉/页脚视图上设置背景。对象库缺少 UITableHeaderFooterView,所以我尝试了在 xib 中创建一个 UIView 并将另一个作为容器视图添加到其中的方法。我担心的是 UITableHeaderFooterView 上没有内容视图出口,我不能确定我的内容视图实际上最终是内容视图。
这听起来像是 hack 或 API 误用,但我没有遇到任何警告或问题:
-
创建 UITableHeaderFooterView 的子类
为其创建一个空的xib
从对象库中拖动一个 UITableViewCell
将 UITableHeaderFooterView 的类分配给该单元格
分配重用标识符
我想知道这种方法的任何(潜在)问题,请发表评论。
【讨论】:
我无法将UITableHeaderFooterView
类分配给单元格。 Xcode 不接受它。【参考方案7】:
UITableViewHeaderFooterView 文档包含registerNib:forHeaderFooterViewReuseIdentifier:
方法
但目前(截至 2013 年 9 月 4 日)Interface Builder 中的对象库不包含 UITableViewHeaderFooterView。 这使得 registerNib:forHeaderFooterViewReuseIdentifier: 无用,因为无法在 nib 中正确配置视图。 也许最好尝试重用单元格...
【讨论】:
【参考方案8】:在 xib 中创建新视图
从 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 的相当滥用,但只要它没有任何大的缺点,我发现它是干净代码和易用性之间的一个很好的权衡。所以这只是一个解决方案,我同意你的观点,不是最干净的。以上是关于界面生成器中的 UITableViewHeaderFooterView的主要内容,如果未能解决你的问题,请参考以下文章