如何从UITableView获取节标题

15
我试图使用以下代码获取节标题视图:

我试图使用以下代码获取节标题视图:

[tableView headerViewForSection:indexPath.section];

但是这段代码总是返回 nil。 你能给我一些示例来获取表格视图的节头视图吗? 这是我的 viewForHeader 实现:

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

  DynamicHeader *headerView = [[DynamicHeader alloc] init];
        headerView.frame = CGRectMake(0, 0, 320, 40);
        UILabel *headerLbl = [[UILabel alloc] init];
        headerLbl.frame = CGRectMake(10, 10, 300, 20);
        if(((SectionViewController *)sharedInstance.currentViewController).currentSectionType == 25)
        {
            UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"minus.png"]];
            imgView.frame = CGRectMake(285, 14.5, 16, 13);
            [headerView addSubview:imgView];
            UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:sharedInstance action:@selector(headerTap:)];
            [headerView addGestureRecognizer:recognizer];
            headerView.tableView = tableView;
            headerView.heightForRows = 95;
            headerView.isOpen = YES;
        }
 headerLbl.text = [[[[[((SectionViewController *)sharedInstance.currentViewController).responseDictionary valueForKey:DATA_PARAMETER] valueForKey:SECTION_TABLE_PARAMETER] objectAtIndex:section] valueForKey:TABLE_SECTION_HEADER] capitalizedString];
 [headerView addSubview:headerLbl];

        return headerView;

}

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

 if((DynamicHeader *)[tableView headerViewForSection:indexPath.section] != nil)
        {
            return ((DynamicHeader *)[tableView headerViewForSection:indexPath.section]).heightForRows;
        }
        else
        {
            return 95;
        }

}


- (void)headerTap: (UITapGestureRecognizer *)recognizer
{
    DynamicHeader *view = (DynamicHeader *)[recognizer view];
    if(view.isOpen)
    {
        view.heightForRows = 0;

    }
    else
    {
        view.heightForRows = 95;
    }
    view.isOpen = !view.isOpen;

    [view.tableView beginUpdates];
    [view.tableView endUpdates];
}

你的 headerViewForSection: 实现是什么(如果有的话)? - Rok Jarc
@rokjarc,目前我正在调用这个方法时,tableview不是nil。此外,我设置了tableview的代理和数据源。 - Kisel Alexander
我看到了:问题似乎出在你的 heightForRowAtIndexPath 方法中 - 不应该有 if((DynamicHeader *)[tableView headerViewForSection:indexPath.section] != nil) 这个条件。 - Rok Jarc
@rokjarc,我设置了这个条件,以防在第一次调用此方法时,部分标题视图尚未创建。 - Kisel Alexander
是的,但是TableView 调用此方法来检查是否需要调用viewForHeader - 因为您返回0,它甚至不会尝试创建 header view。 - Rok Jarc
显示剩余4条评论
6个回答

8

虽然这是一个比较古老的问题,但是也许对其他人来说有解决方案会很有帮助...

UITableView 只会在需要时(例如在表视图内容区域可见)才创建单元格、表头和表尾视图。

如果单元格、表头或表尾视图在表视图中不可见,则 'cellForRowAtIndexPath:'、'headerViewForSection:' 或 'footerViewForSection:' 的调用可能会返回 'nil'。(请参阅 UITableView.h 查看此行为的文档。唯一的例外是视图尚未被表视图回收)

当然,您可以通过直接调用负责代理方法来创建任何表视图子视图,但 UITableView 不会自动执行此操作。

因此,访问单元格、表头或表尾视图的解决方案是首先使它在表视图中可见。

以下是表头视图的示例:

CGRect  sectionHeaderRect = [self.tableView rectForHeaderInSection:groupSectionIndex];
[self.tableView scrollRectToVisible:sectionHeaderRect
                           animated:NO];

// Let the tableview load the needed views
dispatch_async(dispatch_get_main_queue(), ^{

    UITableViewHeaderFooterView*    groupSectionHeaderView = [self.tableView headerViewForSection:sectionIndex];

    // Use groupSectionHeaderView
});

1
在我的情况下,尽管标题可见且索引正确,但它始终返回nil。 - User

3

使用此代理方法访问表头视图:

- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section


2

您是否已经实施了

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

并且

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

你的ViewController子类中有这个方法吗?

如果是,可能你在其中一个方法中遇到了问题。


@KiselAlexander,调用cellForRowAtIndexPath方法是否返回了nil? - Nikita
看看你的viewForHeaderInSection实现,我认为问题就在那里。你在运行时看到标题了吗? - Nikita
尼克,我应该在viewForHeaderInSection中使用dequeueReusableHeaderFooterViewWithIdentifier吗? - Kisel Alexander

1
你的头部视图必须继承自UITableViewHeaderFooterView,否则此调用将不起作用并始终返回nil。

0

你在哪里调用 [tableView headerViewForSection:indexPath.section];

如果你在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中,在 tableView 还未显示时调用它,那么你会得到 nil 返回,因为 tableView 还没有设置好。

如果你在 tableView 加载后的其他地方调用它,你应该会得到一个 UITableViewHeaderFooterView


当tableview已经可见时,我正在调用[tableView headerViewForSection:indexPath.section];在heightForRowAtIndexPath中。 - Kisel Alexander
是的,在 heightForRow 中调用它也会返回 nil。我怀疑表头没有设置好或者在 tableview 计算单元格高度时没有刷新。然而,对于单元格触摸事件不会出现这种情况。如果你有一个自定义的表头视图,也许你可以创建一个 IBOutlet 来引用它? - Keith Kennedy

-1

heightForRowAtIndexPath 在调用 viewForHeaderInSection 之前被调用,所以你当然会得到 nil


我多次调用heightForRowAtIndexPath。一次是在创建tableview时,另一次是在调用[tableview beginUpdates]时。在第二种情况下,我已经为该部分设置了标题。 - Kisel Alexander
请问在heightForRowAtIndexPath中调用headerViewForSection的必要性是什么? - cjd
我有一个自定义的分区头视图,其中包含此部分中所有单元格的高度。我不想在我的主类中有额外的变量,因此我将高度保留在头视图中。 - Kisel Alexander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接