tableView(

编程入门 行业动态 更新时间:2024-10-25 08:20:31
tableView(_:viewforHeaderInSection :)未被调用(tableView(_:viewforHeaderInSection:) Not Being Called)

这个让我发疯。

我有一个视图控制器, UITableViewController子类。 除了视图控制器之外,表视图的数据源被自定义数据源对象替换(默认情况下, UITableViewController既是delgate,也是其表视图的数据源)。 自定义数据源不实现tableView(_:titleForHeaderInSection:)

视图控制器(委托)实现:

tableView(_:viewforHeaderInSection:) tableView(_:heightForHeaderInSection:) tableView(_:estimatedHeightForHeaderInSection)

......都没有被称为。

因此,我的表视图部分不显示任何标题。

如果我指定表视图的全局节标题高度:

override func viewDidLoad() { super.viewDidLoad() tableView.estimatedSectionHeaderHeight = 12 // (say)

...然后显示空白标题,但仍未调用 tableView(_:titleForHeaderInSection:)等,我的自定义标题视图永远不会显示。

之前已经提出了类似的问题,Apple的文档似乎并非100%正确,但我很肯定我正在做所有必需的事情(我已尝试过所有配置)。

我错过了什么?

代码库很大,而不是我的; 也许我错过了一些东西,但不知道还有什么可以找...


更新

我创建了一个新的,最小的项目来测试,事实证明我只需要实现这两个委托方法(而不是修改表视图的任何属性):

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) // (say) view.backgroundColor = UIColor.red // (say) return view } override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 10.0 // (say) }

...显示我的自定义节标题视图。

但是,相同的设置不适用于我现有的项目。 某事,某处必须干扰......


更新2

我放弃了UITableView以查看发生了什么,但仍然无法弄明白(请参阅内联注释):

导入UIKit

class DebugTableView: UITableView { // GETS EXECUTED: required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override var estimatedSectionHeaderHeight: CGFloat { // NEVER GETS EXECUTED: get { return super.estimatedSectionHeaderHeight } // NEVER GETS EXECUTED: set (newValue) { super.estimatedSectionHeaderHeight = newValue } } override var sectionHeaderHeight: CGFloat { // NEVER GETS EXECUTED: get { return super.sectionHeaderHeight } // NEVER GETS EXECUTED: set (newValue) { super.sectionHeaderHeight = newValue } } // NEVER GETS EXECUTED: override func headerView(forSection section: Int) -> UITableViewHeaderFooterView? { let view = super.headerView(forSection: section) return view } // GETS EXECUTED ONCE PER CELL: override func rectForHeader(inSection section: Int) -> CGRect { var rect = super.rectForHeader(inSection: section) rect.size.height = 1000 // HAS NO EFFECT return rect } }

This one is driving me crazy.

I have a view controller, subclass of UITableViewController. The table view's data source is replaced by a custom data source object, other than the view controller (by default, UITableViewController is both the delgate and the data source of its table view). The custom data source does NOT implement tableView(_:titleForHeaderInSection:)

The view controller (the delegate) implements:

tableView(_:viewforHeaderInSection:) tableView(_:heightForHeaderInSection:) tableView(_:estimatedHeightForHeaderInSection)

...neither of which is ever called.

As a result, my table view sections do not display any header.

If I specify the table view's global section header height:

override func viewDidLoad() { super.viewDidLoad() tableView.estimatedSectionHeaderHeight = 12 // (say)

...then blank headers are displayed, but tableView(_:titleForHeaderInSection:) et al are still not called and my custom header views never get displayed.

Similar questions have been asked before, and Apple's docs seems to not be 100% correct, however I am positive that I am doing everything that is required (I have tried all configurations).

What am I missing?

The codebase is large, and not mine; perhaps I am missing something somwehere but don't know what else to look for...


Update

I created a new, minimal project to test and it turns out I only need to implement these two delegate methods (and not modify any properties of the table view):

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100)) // (say) view.backgroundColor = UIColor.red // (say) return view } override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return 10.0 // (say) }

...to have my custom section header view displayed.

However, the same setup does not work on my existing project. Something, somewhere must be interfering...


Update 2

I sublcassed UITableView to see what was going on, but still can't figure it out (see inline comments):

import UIKit

class DebugTableView: UITableView { // GETS EXECUTED: required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override var estimatedSectionHeaderHeight: CGFloat { // NEVER GETS EXECUTED: get { return super.estimatedSectionHeaderHeight } // NEVER GETS EXECUTED: set (newValue) { super.estimatedSectionHeaderHeight = newValue } } override var sectionHeaderHeight: CGFloat { // NEVER GETS EXECUTED: get { return super.sectionHeaderHeight } // NEVER GETS EXECUTED: set (newValue) { super.sectionHeaderHeight = newValue } } // NEVER GETS EXECUTED: override func headerView(forSection section: Int) -> UITableViewHeaderFooterView? { let view = super.headerView(forSection: section) return view } // GETS EXECUTED ONCE PER CELL: override func rectForHeader(inSection section: Int) -> CGRect { var rect = super.rectForHeader(inSection: section) rect.size.height = 1000 // HAS NO EFFECT return rect } }

最满意答案

你只需要设置sectionHeaderHeight ,而不仅仅是估计高度!

喜欢,

tableView.sectionHeaderHeight = UITableViewAutomaticDimension tableView.estimatedSectionHeaderHeight = 25

然后只是覆盖viewForHeaderInSection 。 并且无需覆盖任何其他代表!

I found the problem.

It turns out there was an auxiliary object overtaking the role of table view delegate and hiding it.

This class:

Adopts the UITableViewDelegate protocol and implements most of its methods (but not the header/footer-related ones), Sets itself as the table view's delegate inside the table view controller's viewDidAppear() method, Keeps a reference to the table view controller,

When it's implementation of (say) tableView(_:didSelectRowAtIndexPath:) is called, it in turn calls the table view controller's equivalent method, giving the impression that the view controller is still the delegate:

class ManInTheMiddle: NSObject, UITableViewDelegate { var formerDelegate: UITableViewController? func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { formerDelegate?.tableView(tableView, didSelectRowAt: indexPath) // Do some other stuff... } }

This is why some methods of UITableViewDelegate where being called on my table view controller and some weren't.

I discovered this by overriding the table view's delegate property:

class DebugTableView: UITableView { // ... override var delegate: UITableViewDelegate? { get { return super.delegate } set (newValue) { super.delegate = newValue // < BREAKPOINT HERE } }

...out of desperation (there was no strong reason to suspect the delegate was swapped, being that most methods worked...)

<rant>Damn, do I hate these kind of dirty hacks... This is almost #define true false territory, sheesh... </rant>

更多推荐

本文发布于:2023-07-15 19:15:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1117748.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:tableView

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!