UITableView: 隐藏空节中的标题

我有一个 UITableView,可以显示当月的开支(见截图) :

我的问题是空白部分的标题。有什么办法可以隐藏它们吗? 数据是从核心数据加载的。

这是生成头标题的代码:

标题页眉

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
} else {


NSDate *today = [NSDate date ];
int todayInt = [dataHandler getDayNumber:today].intValue;


NSDate *date = [NSDate dateWithTimeIntervalSinceNow:(-(todayInt-section-1)*60*60*24)];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:[[NSLocale preferredLanguages] objectAtIndex:0]]];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *formattedDateString = [dateFormatter stringFromDate:date];
return formattedDateString;}


}

ViewForHeader

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
} else {


UIView *headerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 30)];
UILabel *title = [[UILabel alloc]initWithFrame:CGRectMake(4, 9, 312, 20)];
UIView *top = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 312, 5)];
UIView *bottom = [[UIView alloc]initWithFrame:CGRectMake(0, 5, 312, 1)];


[top setBackgroundColor:[UIColor lightGrayColor]];
[bottom setBackgroundColor:[UIColor lightGrayColor]];


[title setText:[expenseTable.dataSource tableView:tableView titleForHeaderInSection:section]];
[title setTextColor:[UIColor darkGrayColor]];
UIFont *fontName = [UIFont fontWithName:@"Cochin-Bold" size:15.0];
[title setFont:fontName];




[headerView addSubview:title];
[headerView addSubview:top];
[headerView addSubview:bottom];


return headerView;


}


}

页眉高度

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {


NSLog(@"Height: %d",[tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0);
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section == 0]) {
return 0;
} else {
return 30;
}
}

行数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{


int rows = 0;
for (Expense* exp in [dataHandler allMonthExpenses]) {
if ([exp day].intValue == section) {
rows++;
}
}


return rows;
}

enter image description here Sebastian

68823 次浏览

如果在 -tableView:viewForHeaderInSection:return nil,如果节计数为0。

编辑: 可以使用 numberOfRowsInSection获取节中的元素数。

编辑: 如果 numberOfRowsInSection为0,也许在 titleForHeaderInSection中也应该返回 nil。

编辑: 您是否实现了以下方法?

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

编辑 : Swift 3示例

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
return "Title example for section 1"
}
case 1:
if self.tableView(tableView, numberOfRowsInSection: section) > 0 {
return "Title example for section 2"
}
default:
return nil // when return nil no header will be shown
}
return nil
}

看一下方法 -[UITableViewDelegate tableView:heightForHeaderInSection:],特别是它的文档附注:

在 iOS 5.0之前,表格视图会自动调整高度 对于 tableView:viewForHeaderInSection: 返回一个 nil视图。在 iOS5.0和更高版本中,必须返回实际的 此方法中每个节标头的高度。

对于适当的部分,必须将 tableView:heightForHeaderInSection:设置为0。这是最近发生的一些变化,让我去了几个地方。从 UITableViewDelegate上看。

在 iOS 5.0之前,表格视图会自动调整高度 其中 tableView: viewForHeaderInSection: 返回一个 nil 视图。在 iOS 5.0及更高版本中,必须返回实际的 此方法中每个节标头的高度。

所以你要做的就是

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return 0;
} else {
// whatever height you'd want for a real section header
}
}

我知道这是一个老问题,但我想补充一下。我更喜欢将 titleHeader设置为 nil 的方法,而不是将 heightForHeaderInSection改为0,因为它可能会导致 indexPath从应该位置 + 1的位置出现问题,这是因为头仍然在那里但是被隐藏了。

所以说,建立在 DBD 的答案的基础上,你可以把没有行的部分的 titleForHeaderInSection:设置为 nil,如下所示:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
} else {
// return your normal return
}
}

在我奇怪的处境中,我必须回去:

ViewForHeaderInSection-> nil

ViewForFooterInSection-> nil(别忘了页脚!)

HeightForHeaderInSection-> 0.01(不是0!)

页脚高度-> 0.01

只有在这种情况下空部分完全消失

这似乎是正确的方式,它将正确地动画和工程干净... 正如苹果公司的意图..。

向 tableView 委托提供适当的信息

当部分中没有项目时,返回0.0 f:

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

. . 也返回无:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

对 tableView 进行适当的数据删除

  1. 打电话给 [tableView beginUpdates];
  2. 从 dataSource 中删除项,跟踪元素被删除的位置。
  3. 使用已删除的单元格的索引路径调用 deleteRowsAtIndexPaths
  4. 如果您的数据源中没有任何项目(在这里,您只能看到头部)。调用 reloadSections:重新加载该部分。这将触发正确的动画并隐藏/幻灯片/淡出标题。
  5. 最后调用 [tableView endUpdates];来完成更新。

在2015年使用 iOS8和 Xcode 6时,下面的方法对我很有效:

/* Return the title for each section if and only if the row count for each section is not 0. */


-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{


if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
return nil;
}else{


// here you want to return the title or whatever string you want to return for the section you want to display


return (SomeObject*)someobjectArray[section].title;
}
}

Swift 4.2

将 heightForHeaderInSection 设置为 Zero,如果有自定义节视图,则将不带单元格的节设置为 nil。

func tableView(_ tableView: UITableView,
heightForHeaderInSection section: Int) -> CGFloat {
return height_DefaultSection
}


func tableView(_ tableView: UITableView,
viewForHeaderInSection section: Int) -> UIView? {


return tableView.dataSource?.tableView(tableView, numberOfRowsInSection: section) == 0 ? nil: headerView(tableView: tableView, section: section)
}