部分标题不显示在程序化UITableView中

时间:2017-08-10 19:03:41

标签: ios swift3 interface programmatically-created uitableviewsectionheader

我正在尝试学习如何以编程方式创建不同的UI元素。我的UITableView面临以下问题..

我有2个.swift文件,一方面,我们有......

        struct SettingsView {

        let settingsCustomTable: UITableView = {

            let aTable = UITableView()
                aTable.sectionHeaderHeight = 42
                aTable.tableFooterView = UITableViewHeaderFooterView(frame:CGRect(x:0,
                                                                                  y:0,
                                                                                  width:aTable.frame.width,
                                                                                  height:0))

                aTable.register(SettingsCustomHeader.self, forHeaderFooterViewReuseIdentifier:"customHeader")
                aTable.register(SettingsCustomCell.self, forCellReuseIdentifier:"customCell")

            return aTable
        }()

    }


    ////////////////////////////////
    //  custom cell class below   //
    ////////////////////////////////

    private class SettingsCustomCell: UITableViewCell {

        override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)

            contentView.addSubview(customCellLabel)
            customCellLabel.frame = CGRect(x:16,
                                           y:0,
                                           width: self.frame.width,
                                           height:self.frame.height)
        }

        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

        private let customCellLabel: UILabel = {

            let aLabel = UILabel()
                aLabel.text = "custom label"
                aLabel.textColor = appGreenColor(alphaIs: 1)

            return aLabel
        }()
    }


    //////////////////////////////////
    //  custom header class below   //
    //////////////////////////////////

    private class SettingsCustomHeader: UITableViewHeaderFooterView {

        override init(reuseIdentifier: String?) {
            super.init(reuseIdentifier: reuseIdentifier)

            contentView.addSubview(customHeaderLabel)
            customHeaderLabel.frame = CGRect(x:0,
                                           y:0,
                                           width: self.frame.width,
                                           height:self.frame.height)
        }

        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

        private let customHeaderLabel: UILabel = {

            let aLabel = UILabel()
            aLabel.text = "custom header"
            aLabel.textColor = UIColor.white
            aLabel.backgroundColor = UIColor.red

            return aLabel
        }()

    }

在另一个.swift文件中,我有如下控制器..

class SettingsVC: UIViewController, UITableViewDelegate, UITableViewDataSource {

    private let instanceOfSettingsView = SettingsView()

    override func loadView() {
        super.loadView()

        instanceOfSettingsView.settingsCustomTable.delegate = self
        instanceOfSettingsView.settingsCustomTable.dataSource = self

        view.addSubview(instanceOfSettingsView.settingsCustomTable)
        instanceOfSettingsView.settingsCustomTable.frame = CGRect(x: 0,
                                                                  y: 0,
                                                                  width: self.view.frame.width,
                                                                  height: self.view.frame.height)

    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 2
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath)
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return tableView.dequeueReusableHeaderFooterView(withIdentifier: "customHeader")
    }

正如您所看到的,我对单元格和标题部分使用完全相同的方法。但由于一些奇怪的原因,我得到以下输出(请查看本文末尾的截图) ..

你能告诉我我错过了什么..?我试图将我的视图与我的控制器分开,除了那个小部分之外,这个控制器是成功的。

感谢您的帮助。

enter image description here

1 个答案:

答案 0 :(得分:1)

在自定义标题的初始函数中添加一行:

   override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)

        contentView.addSubview(customHeaderLabel)
        customHeaderLabel.frame = CGRect(x:0,
                                       y:0,
                                       width: self.frame.width,
                                       height:self.frame.height)

        // add this line
        print("w:", self.frame.width, "h:", self.frame.height)
    }

您将看到,此时未设置框架。您的调试控制台输出应为:

w: 0.0 h: 0.0
w: 0.0 h: 0.0

如果您在customHeaderLabel上设置约束而不是设置其框架,则应该看到标签。 (它也可以帮助设置背景颜色,这样你就可以看到了什么)。

所以,要#34;填写"这个答案......

使用视觉格式语言:

override init(reuseIdentifier: String?) {
    super.init(reuseIdentifier: reuseIdentifier)

    contentView.addSubview(customHeaderLabel)

    customHeaderLabel.translatesAutoresizingMaskIntoConstraints = false

    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[chl]|", options: [], metrics:[:], views:["chl":customHeaderLabel]))
    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|[chl]|", options: [], metrics:[:], views:["chl":customHeaderLabel]))

}

或使用锚点和.constraint格式:

override init(reuseIdentifier: String?) {
    super.init(reuseIdentifier: reuseIdentifier)

    contentView.addSubview(customHeaderLabel)

    customHeaderLabel.translatesAutoresizingMaskIntoConstraints = false

    customHeaderLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8.0).isActive = true
    customHeaderLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0.0).isActive = true
    customHeaderLabel.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0.0).isActive = true
    customHeaderLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0.0).isActive = true

}