当节为空时,分组的UITableView显示空白区域

时间:2010-03-22 21:34:11

标签: iphone objective-c uitableview

我有一个分组的UITableView,其中并非所有部分都可以同时显示,该表由一些并非每条记录都有的数据驱动。我的麻烦是没有某些部分的记录在表格中显示为空白(见图)

alt text http://img220.imageshack.us/img220/5633/screenshot20100322at228.png

没有页脚/标题。我错过了什么?

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self getRowCount:section];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

cell.textLabel.text = [NSString stringWithFormat:@"section: %d row: %d",indexPath.section,indexPath.row];
// Configure the cell...

return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    float height = 0.0;

    if([self getRowCount:indexPath.section] != 0){
        height = kDefaultRowHeight;
    }

    return height;

}

11 个答案:

答案 0 :(得分:40)

我有类似的情况,如果我可以让它的空白部分,我的数据模型确实更好。

如果在tableview控制器中设置self.tableView.sectionHeaderHeight = 0;self.tableView.sectionFooterHeight = 0;,则可以解决您的问题。这些必须为0,因为委托方法以某种方式忽略返回值0.然后你必须覆盖一些委托方法:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if (section==0)
        return sectionGapHeight;
    if ([self tableView:tableView numberOfRowsInSection:section]==0) {
        return 0;
    }
    return sectionGapHeight;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    if (section==[self numberOfSectionsInTableView:tableView]-1) {
        return sectionGapHeight;
    }
    return 0;
}
- (UIView *)sectionFiller {
    static UILabel *emptyLabel = nil;
    if (!emptyLabel) {
        emptyLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        emptyLabel.backgroundColor = [UIColor clearColor];
    }
    return emptyLabel;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return [self sectionFiller];
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
    return [self sectionFiller];
}

此代码还将使节之间的间隙与第一节之前的间隙和最后一节之下的间隙的高度相同。在我看来,这比默认情况看起来更好,其中间距是顶部和底部的两倍。

答案 1 :(得分:17)

这是适合我的解决方案

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    switch (section) {  
      case 1: case 3: case 5: return 20.0f; break;
      default: return 0.01f; // for some reason 0 is not accepted - give something :)
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    switch (section) {  
      case 1: case 3: case 5: return 20.0f; break;
      default: return 0.01f; // for some reason 0 is not accepted - give something :)
    }
}

答案 2 :(得分:6)

在上面的屏幕截图中,您的numberOfSectionsInTableView:方法返回的值是5吗?然后,您的getRowCount:方法(从numberOfRowsInSection:调用)为那些“缺失”部分(例如1,3和4)返回值0?

如果您不希望介于两者之间,可能的解决方案是仅声明您想要显示的部分数量。在上面的示例中,您只想从numberOfSectionsInTableView:返回值3。

答案 3 :(得分:4)

此解决方案基于user362178解决方案。但保持各部分的标签完好无损:

定义代码顶部的某处:

#define HEIGHT_FOR_HEADER_AND_FOOTER 50

添加到视图中加载:

self.tableView.sectionHeaderHeight = 0;
self.tableView.sectionFooterHeight = 0; 

添加以下方法:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{
    // Needed because if this does not return a value, the header label of the section will
    // be at the top of the screen.
    if (section == 0)
    {
        return HEIGHT_FOR_HEADER_AND_FOOTER;
    }

    if ([self tableView:tableView numberOfRowsInSection:section] == 0) 
    {
        return 0;
    }
    else   
    {
        return HEIGHT_FOR_HEADER_AND_FOOTER;
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{
    // if last section
    if (section == [self numberOfSectionsInTableView:tableView] - 1) 
    {
        return HEIGHT_FOR_HEADER_AND_FOOTER;
    }

    return 0;
}

答案 4 :(得分:3)

以下是我根据此处的所有答案找到的最优雅的解决方案,加上this answer

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

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

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) {
        return 0.01f;;
    }

    return UITableViewAutomaticDimension;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
    if ([self tableView: tableView numberOfRowsInSection: section] == 0) {
        return 0.01f;;
    }

    return UITableViewAutomaticDimension;
}

答案 5 :(得分:1)

我在iOS 7中遇到了同样的问题,最后我解决了这个检查Header for Header和Footer部分的高度,正如Ramesh所说:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 
if ([[self.tableView objectAtIndex:section] count] == 0)
    return 0.01f;
else
    return 30.f;

}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
return 0.01f;

}

很奇怪,但是如果你设置0.f作为高度,那么这些部分会显示为默认大小并向下移动到其他部分。

答案 6 :(得分:1)

在这种情况下,有一个方便的值称为CGFloat.leastNonzeroMagnitude。如下使用它:

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

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return .leastNonzeroMagnitude
}

您也可以使用tableView.sectionHeaderHeight = 0tableView.sectionFooterHeight = 0,但这将应用于所有页眉和页脚。使用委托解决方案,您仍然可以操纵不同的页眉和页脚的高度,但是使用.leastNonzeroMagnitude作为默认值

答案 7 :(得分:0)

我相信,对于节表视图,每个节必须存在,并且每个节都有标题和页脚的缓冲空间,无论你将文本放在其中。您需要做的是删除未使用的部分。在您的示例中,您将删除第1,3和4部分。这意味着:

“section 0”是indexPath.section == 0

“第2节”是indexPath.section == 1

“第5节”是indexPath.section == 2

如果以这种方式编码,将删除页眉和页脚,因为删除了nil单元格。

当然这不是正确的编码,但我只是想让你了解神学。 希望这会有所帮助。

答案 8 :(得分:0)

关键是将表格视图的sectionHeaderHeightsectionFooterHeight设置为零。

您可以在viewDidLoad或storyboard / xib中的用户定义的运行时属性部分执行此操作。出于某种原因,在“大小检查器”选项卡中,您无法将页眉或页脚高度设置为低于1.

我发现,一旦我这样做,我就不需要以特殊方式覆盖任何其他委托方法。我只是从0返回numberOfRowsInSection,从nil返回titleForHeaderInSection的空白部分,它们在我的表格视图中不会占用任何空间。

具有标题的部分会自动获得正确的标题大小,并且表格视图的顶部仍然具有默认空格。

答案 9 :(得分:0)

我通过在初始化tableView的地方设置tableView的 dataSource delegate 解决了这个问题。

注意:请记住,初始化tableView时可能需要延迟tableView进行分配。

lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.separatorStyle = .none
        tableView.backgroundColor = .white
        tableView.dataSource = self
        tableView.delegate = self
        return tableView
    }()

答案 10 :(得分:0)

我通过设置tableView的 dataSource delegate 在初始化tableView的地方解决了该问题

请记住,初始化tableView时可能需要延迟tableView进行分配

lazy var tableView: UITableView = {
        let tableView = UITableView(frame: .zero, style: .grouped)
        tableView.separatorStyle = .none
        tableView.backgroundColor = .white
        tableView.dataSource = self
        tableView.delegate = self
        return tableView
    }()