tableView(_:viewforHeaderInSection :)未被调用

时间:2017-04-14 08:22:09

标签: ios uitableview

这个让我发疯。

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

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

    ......两者都没有被召唤过。

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

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

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

2 个答案:

答案 0 :(得分:1)

您还需要设置 tableView.sectionHeaderHeight = UITableViewAutomaticDimension tableView.estimatedSectionHeaderHeight = 25 ,而不仅仅是估计身高!

viewForHeaderInSection

然后只需覆盖var points = [1, 2, 4, 9]; var connections = [ [1, 2], [1, 4], [1, 9], [2, 4], [4, 9] ]; connections.sort(); var missing = []; var currentIndex = 0; for (var i = 0; i < points.length; i++) { for (var j = i + 1; j < points.length; j++) { if (connections[currentIndex][0] == points[i] && connections[currentIndex][1] == points[j]) { currentIndex++; } else { missing.push([points[i], points[j]]); } } } console.log(missing); 。并且无需覆盖任何其他代表!

答案 1 :(得分:0)

我发现了问题。

事实证明,有一个辅助对象超越了表视图委托的角色并将其隐藏起来。

这堂课:

  • 采用UITableViewDelegate协议并实施大多数其方法(但与页眉/页脚相关的方法),
  • 在表格视图控制器的viewDidAppear()方法中将自己设置为表格视图的委托,
  • 保留对表视图控制器的引用,
  • 当调用(例如)tableView(_:didSelectRowAtIndexPath :)的实现时,它又会调用表视图控制器的等效方法,给人的印象是视图控制器是代表:

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

这就是为什么 UITableViewDelegate的一些方法在我的表格视图控制器上被调用而有些不是。

我通过覆盖表格视图的delegate属性

来发现这一点
class DebugTableView: UITableView {

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

...出于绝望(没有充分的理由怀疑委托被交换,因为大多数方法都有效......)

&lt; rant&gt;该死的,我讨厌这些肮脏的黑客......这几乎是#define true false领域,sheesh ...... &LT; /咆哮&GT;