ios UITableView:隐藏空白部分的标题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9737616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:21:42  来源:igfitidea点击:

UITableView: hide header from empty section

objective-ciosuitableviewtableview

提问by Sebastian Flückiger

i have a UITableView, that displays expenses from a current month (see screenshot):

我有一个 UITableView,显示当月的费用(见截图):

My problem is with the header for empty sections. is there any way to hide them? The data is loaded from coredata.

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

this is the code that generates the header title:

这是生成标题标题的代码:

TitleForHeader

标题标题

-(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;

}

}

heightForHeader

标题高度

- (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;
}
}

numberOfRowsInSection

截面行数

- (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 heresebastian

在此处输入图片说明塞巴斯蒂安

采纳答案by LuisEspinoza

What if in – tableView:viewForHeaderInSection:you return nilif the section count is 0.

如果在 -如果节数为 0,tableView:viewForHeaderInSection:你会怎样return nil

EDIT: You can use numberOfRowsInSectionfor obtaining the number of elements in the section.

编辑:您可以numberOfRowsInSection用于获取该部分中的元素数量。

EDIT: Probably you should return nil also in titleForHeaderInSectionif numberOfRowsInSectionis 0.

编辑titleForHeaderInSection如果numberOfRowsInSection是 0,您可能也应该返回 nil 。

EDIT: Did you implement the following method?

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

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

EDIT: Swift 3example

编辑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
}

回答by DBD

You have to set tableView:heightForHeaderInSection:to 0 for the appropriate sections. This is something which changed fairly recently and got me in a couple places. From UITableViewDelegateit says...

您必须tableView:heightForHeaderInSection:为适当的部分设置为 0。这是最近发生的变化,让我在几个地方。从UITableViewDelegate它说...

Prior to iOS 5.0, table views would automatically resize the heights of headers to 0 for sections where tableView:viewForHeaderInSection: returned a nil view. In iOS 5.0 and later, you must return the actual height for each section header in this method.

在 iOS 5.0 之前,对于 tableView:viewForHeaderInSection: 返回 nil 视图的部分,表格视图会自动将标题的高度调整为 0。在 iOS 5.0 及更高版本中,您必须在此方法中返回每个部分标题的实际高度。

So you'll have to do something like

所以你必须做类似的事情

- (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
    }
}

回答by djdance

In my strange situation I have to return:

在我奇怪的情况下,我必须返回:

?viewForHeaderInSection -> nil

? viewForFooterInSection -> nil (don't forget about footer!)

?heightForHeaderInSection -> 0.01 (not zero!)

? heightForFooterInSection -> 0.01

?viewForHeaderInSection -> nil

? viewForFooterInSection -> nil (不要忘记页脚!)

?heightForHeaderInSection -> 0.01(不是零!)

? heightForFooterInSection -> 0.01

only in this case empty sections disappear completely

只有在这种情况下,空白部分才会完全消失

回答by Sixten Otto

Take a look at the method -[UITableViewDelegate tableView:heightForHeaderInSection:]. Especially the note that accompanies its documentation:

看一看方法-[UITableViewDelegate tableView:heightForHeaderInSection:]。尤其是其文档随附的注释:

Prior to iOS 5.0, table views would automatically resize the heights of headers to 0 for sections where tableView:viewForHeaderInSection:returned a nilview. In iOS 5.0 and later, you must return the actual height for each section header in this method.

之前的iOS 5.0,表视图将自动地调整大小标头的高度为0,其中的部分tableView:viewForHeaderInSection:返回的nil图。在 iOS 5.0 及更高版本中,您必须在此方法中返回每个部分标题的实际高度。

回答by gav

I know this is an old question but I'd like to add to it. I prefer the approach of setting the titleHeaderto nil over altering the heightForHeaderInSectionto 0 as it can cause problems with indexPathbeing +1 from where is should be due to the header still being there but hidden.

我知道这是一个老问题,但我想补充一下。我更喜欢将 设置titleHeader为 nil的方法而不是将 0 更改heightForHeaderInSection为 0 的方法,因为它可能会导致indexPath+1 的问题,因为标题仍然存在但隐藏。

So with that said and building on DBD's answeryou can set the titleForHeaderInSection:to nil for sections with no rows in it like so:

因此,随着中说,建设上DBD的回答,您可以设置titleForHeaderInSection:为零的一个不带行,像这样几个部分:

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

回答by Ronaldoh1

In 2015 using iOS 8 and Xcode 6, the following worked for me:

在 2015 年使用 iOS 8 和 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;
    }
}

回答by Andres Canella

This seems to be the proper way, It will animate correctly & works clean... as Apple intended...

这似乎是正确的方法,它会正确地设置动画并干净地工作......正如Apple所希望的......

Provide appropriate info to the tableView delegate

为 tableView 委托提供适当的信息

When no items in section, Return 0.0f in:

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

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

..Also return nil for:

..对于以下情况也返回 nil:

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

Do appropriate data removal for tableView

对 tableView 进行适当的数据删除

  1. Call [tableView beginUpdates];
  2. Remove items from your dataSource, keeping track of where elements got removed..
  3. Call deleteRowsAtIndexPathswith the indexPaths of the cells you removed.
  4. if your datasource has no items in it (Here you would end up with just the header). Call reloadSections:to reload that section. This will trigger the correct animation and hide/slide/fade the header.
  5. Finally call [tableView endUpdates];to finish the update..
  1. 称呼 [tableView beginUpdates];
  2. 从数据源中删除项目,跟踪元素被删除的位置..
  3. deleteRowsAtIndexPaths使用您删除的单元格的 indexPaths调用。
  4. 如果您的数据源中没有任何项目(在这里您最终只会得到标题)。调用reloadSections:以重新加载该部分。这将触发正确的动画并隐藏/滑动/淡化标题。
  5. 最后调用[tableView endUpdates];完成更新..

回答by user550088

Swift 4.2

斯威夫特 4.2

Set the heightForHeaderInSection to Zero and if you've a custom section view, set it to nil for sections without cells.

将 heightForHeaderInSection 设置为零,如果您有自定义剖面视图,则将没有单元格的部分的高度设置为 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)
    }