UITableView:viewForHeaderInSection:在reloadData期间未调用:


127

我已经使用正确的委托和数据源链接设置了tableview。。reloadData方法调用数据源和除之外的委托方法viewForHeaderInSection:

为什么呢?


30
heightForHeaderInSection:执行?
2013年

您是否为TableView设置了一个值sectionHeaderHeight
卡特·梅德林

Answers:


256

使用的tableView:viewForHeaderInSection:要求还必须实现tableView:heightForHeaderInSection:。这应该为标题返回适当的非零高度。还要确保您还没有实现tableView:titleForHeaderInSection:。您只能使用其中一个(viewForHeadertitleForHeader)。


3
确保方法签名中没有错字。一封错误的字母表示将不会被调用。也检查情况。另外,请确保您要从返回0 numberOfSections
rmaddy13 2013年

一切都正确并正确编译..我想了解的问题是关于何时调用该方法的时机。.tableView:viewForHeaderInSection在表将要显示而不是作为[ tableview reloadData]
inforeqd

@maddy OMG,谢谢,我是如此愚蠢,我创建了实例,但没有追加到数组中
Happiehappie

4
绝对可以两者兼而有之。viewForHeaderInSection:将优先于titleForHeaderInSection:唯一的要求是,您在表格视图上设置的EstimateSectionHeaderHeight不得为0,否则viewForHeaderInSection:永远不会被调用
romrom

添加到@romrom的注释:如果您同时实现了 titleForHeaderInSection:viewForHeaderInSection:并且从后者返回的视图是的子类,UITableViewHeaderFooterView则它textLabel.text会自动设置为titleForHeaderInSection:字符串的全大写版本。为避免这种情况,请不要实施titleForHeaderInSection:或使用自定义标签而不是Inherited textLabel
Ortwin Gentz '18

40

诀窍是这两种方法属于不同的UITableView协议:tableView:titleForHeaderInSection:是一种UITableViewDataSource协议方法,其中tableView:viewForHeaderInSection属于UITableViewDelegate

这意味着:

  • 如果您实现这些方法,但仅将自己分配 dataSourceUITableView,则您的 tableView:viewForHeaderInSection实现将被忽略。

  • tableView:viewForHeaderInSection具有更高的优先级。如果你同时实现的方法和分配自己作为这两个 dataSourcedelegateUITableView,您将返回意见的部分信息,但是你 tableView:titleForHeaderInSection:会被忽略。

我也尝试删除tableView:heightForHeaderInSection:; 它工作正常,似乎没有影响上述过程。但是文档说,这是tableView:viewForHeaderInSection正常工作所必需的;因此,为了安全起见,最好也执行此操作。


6
你让我今天一整天都感觉很好!!!忘记分配UITableViewDelegateself,因为我认为这tableView:viewForHeaderInSection是一种UITableViewDataSource方法。谢谢!
denis631 '16

1
“ tableView:viewForHeaderInSection”不是至关重要的。重要的是您以某种方式返回身高。您可以通过1.估算或2.硬编码值或3. titleForHeader具有内在大小的a来实现。固有大小是根据字体系列和大小计算的。
亲爱的

28

@rmaddy说错了规则,两次:在现实中,tableView:viewForHeaderInSection:不是要求您还实现了tableView:heightForHeaderInSection:,而且它是完全没有同时调用titleForHeaderviewForHeader。我将仅出于记录目的正确陈述规则:

规则很简单,viewForHeader除非您以某种方式为标头设置高度,否则不会调用该规则。您可以通过以下三种方式的任意组合来执行此操作:

  • 实施tableView:heightForHeaderInSection:

  • 设置表格的sectionHeaderHeight

  • 调用titleForHeader(如果没有,则以某种方式为标头提供默认高度)。

如果您不执行任何操作,viewForHeader则将没有标题,也不会被调用。那是因为没有高度,运行时将不知道如何调整视图的大小,因此不必费心去寻找一个视图。


从文档中获取tableView:viewForHeaderInSection::“此方法仅在tableView:heightForHeaderInSection:实现时才正确运行。”。
rmaddy14年

1
精细。他们说的是文档所说的。现在进行实验。事实如我所说。
马特2014年

以及如何同时拥有titleForHeaderInSectionviewForHeaderInSection?表格视图将仅调用两者之一(我忘记了当前优先级)。
rmaddy14年

1
实际上,还有另外一个难题,那就是有时 viewForHeader调用这三个方法都不会指定高度的这三种方式中的任何一种。我曾经发生过这种情况,在那儿我viewForHeader被打电话给我,标题出现得很好,直到一天,我没有任何改变,但他们没有。从那时起,我开始尝试发现什么是最低要求viewForHeader。现在我知道了。现在你也是如此。
马特2014年

2
@texas不,我不做xamarin。在Cocoa框架之上添加另一个间接级别只会使我大吃一惊。:)
马特

20

给予estimatedSectionHeaderHeightsectionHeaderHeight值固定我的问题。例如, self.tableView.estimatedSectionHeaderHeight = 100 self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension


升级到Swift 3.1之后,我的问题开始了。此解决方案将其修复。
zevij

@pbuchheit苹果文件说,这是可以从iOS 7.0以上版本,请看看这里,developer.apple.com/documentation/uikit/uitableview/...
Sharukh Mastan

@Sharukh Mastan看起来您是正确的。出于某种原因,当我尝试使用该属性时收到警告,但是在执行干净的构建后它消失了。
pbuchheit

7

离开rmaddy的答案,我试图隐藏Header视图,并为“ tableView:heightForHeaderInSection”返回0.0f,从返回0f height视图tableView:viewForHeaderInSection

从更改return 1.0freturn 0.0fin后tableView:heightForHeaderInSectiontableView:viewForHeaderInSection确实调用了委托方法。

原来我想要的效果工作而不必使用“ tableView:heightForHeaderInSection”; 但这对于其他人在调用“ tableView:heightForHeaderInSection”委托方法时遇到问题可能很有用。


5

您应该实现tableView:heightForHeaderInSection:并设置页眉的高度> 0。

该委托方法与viewForHeaderInSection:方法一起使用。

我希望这有帮助。

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
         return 40;
}

您是否测试过答案确实有效?因为如果您仔细阅读,则说明最初调用了viewForHeaderInSection。仅在重新加载表时才调用它!
卡利斯(Karlis)

5

值得一提的是,如果您执行tableView:heightForHeaderInSection:return UITableViewAutomaticDimension,则tableView:viewForHeaderInSection:不会被调用。

UITableViewAutomaticDimension假定UITableViewHeaderFooterView将使用由委托方法填充的标准tableView:titleForHeaderInSection:

来自的评论UITableView.h

返回从该值tableView:heightForHeaderInSection:tableView:heightForFooterInSection:导致高度,从返回适合的值tableView:titleForHeaderInSection:或者tableView:titleForFooterInSection:如果标题不为零。


1
如果您设置estimatedSectionHeaderHeight为某个值,tableView:viewForHeaderInSection则会被调用(类似于行的自动尺寸的工作原理)
GreatWiz

有趣,谢谢。回到7.1时,这种估计高度的微妙性对于单元格很重要,因此标头的情况也可能如此-但现在并不十分重要
约翰

3

我只是遇到了一个问题,即标题未显示iOS 7.1,但与我测试过的更高版本(明确地使用8.1和8.4)一起正常工作。

对于完全相同的代码,7.1 根本没有调用任何节标题委托方法,包括:tableView:heightForHeaderInSection:tableView:viewForHeaderInSection:

经过实验后,我发现从7.1的标头中删除此行会viewDidLoad重新出现,并且不会影响我测试的其他版本:

// _Removing_ this line _fixed_ headers on 7.1
self.tableView.estimatedSectionHeaderHeight = 80;

…因此,至少在7.1版本中似乎存在某种冲突。


3

我也发生了同样的问题,但是由于我使用的是xCode 9中的自动高度计算,因此我无法如上所述给出任何明确的高度值。经过一些试验,我得到了解决方案,我们必须重写此方法,因为,

-(CGFloat)tableView:(UITableView *)tableView 
         estimatedHeightForHeaderInSection:(NSInteger)section
{
      return 44.0f;
}

虽然我已经检查了两个选项

  1. 自动高度计算
  2. 自动估算高度

正如苹果所说,是从情节提要中获得的,但仍然出现了这个奇怪的错误。

请注意:此错误仅在IOS-10版本上显示,而不在IOS-11版本上显示。也许这是xCode的错误。谢谢


0

这就是我所发现的(Swift 4)(感谢对另一个问题的评论

无论我使用titleForHeaderInSection还是viewForHeaderInSection-滚动表格视图和加载新单元格时都不会调用它们,但是我为headerView的textLabel所做的任何字体选择仅出现在加载时最初可见的位置,而不是在滚动表时显示。

修复方法是willDisplayHeaderView:

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    if let header = view as? UITableViewHeaderFooterView {
        header.textLabel?.font = UIFont(name: yourFont, size: 42)
    }
}

0

就我而言,我已经创建了使用UITableviewCell并返回viewForHeaderInSection像这样的单元格的标题视图

return cell

改成

return cell.contentView 

为我工作。



0

之所以viewForHeaderInSection不会被呼叫,是因为以下两个原因之一:

您没有设置您的UITableViewDelegate,或者您设置UITableViewDelegate不正确。


0

就我而言,原因是我没有实现:

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat

-1

有时在或方法中设置tableview.delegate或可能导致此问题。确保不要这样做...datasource = nilviewWillAppear:viewDidAppear:


-1

我将以下两个方法从Swift 2项目剪切并粘贴到了我的Swift 3项目中,但从未调用过这些方法,因为在Swift 3中,这些方法在第一个参数名称之前必须带有“-”。

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

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

    let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: B2BTrolleyHeaderFooterView.reuseIdentifier) as! B2BTrolleyHeaderFooterView        
    return headerView
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.