我有一个UITableView,在某些情况下,某些部分有零行。我的目标是,当这是真的,我不希望在表视图中浪费任何空间,它看起来应该没有数据。
我遇到的问题是这些部分的页眉和页脚,即使没有行也会显示,尽管我重写了委托方法以返回0.0f。
这是它的样子 - 你可以在那里看到顶部约20p的灰色空间,每个约10p的页眉和页脚用于0行的部分。
(来源:hanchorllc.com)
这是我的伪代码:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if ([section hasRow]) {
return 10.0f;
} else {
return 0.0f;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if ([section hasRow]) {
return 10.0f;
} else {
return 0.0f;
}
}
我已经验证了这些方法正在被调用,并且正在执行正确的执行路径。
一个皱纹 - 这个视图控制器正在使用XIB,并且UITableView的节头和页脚值设置为10.0(默认值),尽管我认为它被委托方法覆盖,如果实现的话。
这是一款定位于3.0的应用。
我究竟做错了什么?
在iPhone上的“分组”UITableView中,它仍然会为页眉和页脚呈现最小高度,有效地忽略您的代码将其设置为零。它没有链接到XIB默认值。
这是因为零高度部分页眉或页脚看起来很奇怪。因此Apple已经下令不能将标题高度设置为0.因此,根据您的屏幕截图,多个“空”部分将呈现奇怪的结果。
我担心这一切都是因为当没有数据行时你清除标题大小是错误的;相反,你不应该为空部分调用任何方法。这是一个糟糕的技术,因为基本上iPhone必须调用比它应该更多的方法,并且你渲染的标题比你想要的多(通常 - 有时人们想要留下那里的空白标题,例如用于拖放) 。
因此,例如,让我们假设您有许多部分,但只有部分部分具有多个部分(可能基于用户设置/过滤器)。
实现它的错误方法是:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return totalNumberOfPossibleSections;
}
然后对于每个部分,您没有结果:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (![section hasRow]) return 0;
}
和
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
if (![section hasRow]) return 0.0f;
}
实现它的正确方法是:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return numberOfSectionsWhichHaveAtLeastOneRowInThem;
}
然后每个部分至少会有一个结果。这样,甚至没有渲染没有数据的部分,甚至没有为它们调用方法。注意:我的两个变量名称用于表示它们包含的内容!它们不是特殊的Apple变量......
希望有所帮助!
这有点棘手,因为不接受0.0f值。但任何接近于零的东西都可以解决问题。如果您决定不是像素完美并且想要圆形数字,那么1.0f将几乎相同,因为1px的高度差异将是相当明显的。
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
if(section == 1 )
return 0.000001f;
else return 44.0f; // put 22 in case of plain one..
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 0.000001f; //removing section footers
}
只有当tableView:heightForHeaderInSection:
不是tableView:viewForHeaderInSection:
,或者如果nil
不是tableView:titleForHeaderInSection:
或nil
时,该表似乎尊重@""
。对于页脚高度也是如此。
因此,假设您没有任何节标题视图或标题,只需将其添加到您的表委托:
- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}
我有一个类似的问题:我从XIB(与你相同)加载UITableView
,并为tableView:heightForFooterInSection
(与你相同)的某些部分页脚提供0高度,但该值被忽略。
修复很简单:在XIB中还将页脚高度设置为0.0。 (在Interface Builder中选择Table View,按Command-3查看Size Inspector,查找顶部附近的页脚高度字段)
完成后,它遵循预期的自定义页脚高度。 (也许它将XIB页脚高度视为最小值?)
我发现在我的情况下需要2件事来杀死幻影页脚:
1)将表格视图sectionFooterHeight
设置为0
,即在viewDidLoad
中添加:
tableView.sectionFooterHeight = 0
2)添加委托方法:
override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
return UIView(frame: CGRect.zero)
}
(使用Swift 2.2)
这个对我有用:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
tableView.sectionHeaderHeight = (section == 0 ? 10 : 0);
return tableView.sectionHeaderHeight;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
tableView.sectionFooterHeight = (section == 0 ? 20 : 4);
return tableView.sectionFooterHeight;
}
实际上,对我来说,它正在发生反过来。我已经在xib中将节标题指定为10,但是对于第一节,我想要一个大小标题的标题。我在我的UITableViewCotroller中使用此方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section==0)
return 125;
return tableView.rowHeight;
}
但是即使该方法被调用,节标题高度也不会改变。
我对这个问题的解决方案是开启和关闭h4xxr如何描述,但是我有一个稍微不同的方法来构建动态数量的部分。
首先,我定义了一个方法,它将遍历我的数据结构并标记数据是否应该显示在表中。此标志存储在一个数组中,以便我可以包含尽可能少的部分或多个部分。如果我们只关注每个部分的单元格数量,我可以更好地描述这个实现:
假设我的第一部分是姓名,姓氏和年龄的联系方式。我将使用id为'1'定义此部分(虽然技术上我稍后会解释这可能是任何数字)。现在,如果我的方法确定此部分应该可见,我将值'1'推送到数组。
我希望展示的下一部分是地址,可能有3-4行/单元格。如上所述,我的方法中的逻辑通过将数字“2”推到数组上来确定地址应该是否可见。
现在.. ..如果我们想要两个部分都可见,我们将有一个长度为2的数组和两个项目[1,2]。如果我们只希望联系人详细信息可见,那么我们的数组的长度为1,只有地址[1]和[2]。
现在我们可以返回数组的长度来定义我们想要的部分数量。
我们的switch语句现在看起来像这样:
switch(ourArray[indexPath.section]){
case 1:
<Return the number of rows for the contact details which we said would be 3>
break;
case 2:
<Return the number of rows for the address details which we said would be 4>
break;
case 3:
<Return another number for some section that is referenced by the id '3'>
break;
}
注意我已将案例3放在我的交换机中。因为我们示例中的数组只包含值'1'和'2',所以除非我们决定通过将它推送到数组来添加/启用这种情况,否则情况3将永远不会匹配并被忽略。
另请注意,我们可以在定义哪些部分可见的逻辑的方法中,通过在数组中的不同位置插入/推送它们来更改部分的顺序。
我虔诚地使用上面的内容,因为它允许我解耦部分的索引和构造。
最后,在我使用'reloadData'更新我的表之前,我将调用我的方法,它将构造数组并提供正确的段ID的长度和顺序,以允许我的tableview知道如何构建自己。如果我的数据发生变化或以某种方式过滤,我将再次调用此方法并重建数组。