在自定义UITableViewHeaderFooterView中的现有textLabel上添加约束

时间:2019-07-08 10:51:33

标签: ios swift uitableview constraints ios-autolayout

我想在表标题的textLabel旁边添加一个简单的计数器,用于统计表中对象的数量。因此,我创建了此类:

import UIKit

class CounterHeaderView: UITableViewHeaderFooterView {
    static let reuseIdentifier: String = String(describing: self)

    var counterLabel: UILabel

    override init(reuseIdentifier: String?) {
        counterLabel = UILabel()
        super.init(reuseIdentifier: reuseIdentifier)

        contentView.addSubview(counterLabel)

        counterLabel.translatesAutoresizingMaskIntoConstraints = false
        counterLabel.backgroundColor = .red

        if let textLabel = self.textLabel{
            counterLabel.leadingAnchor.constraint(equalTo: textLabel.trailingAnchor, constant: 6.0).isActive = true
            counterLabel.topAnchor.constraint(equalTo: textLabel.topAnchor).isActive = true
            counterLabel.heightAnchor.constraint(equalToConstant: 24.0).isActive = true
        }

    }

    required init?(coder aDecoder: NSCoder) {
        counterLabel = UILabel()
        super.init(coder: aDecoder)
    }
}

但是运行此命令会导致以下错误:

'Unable to activate constraint with anchors 
<NSLayoutXAxisAnchor:0x60000388ae00 "UILabel:0x7fb8314710a0.leading"> 
and <NSLayoutXAxisAnchor:0x60000388ae80 "_UITableViewHeaderFooterViewLabel:0x7fb8314718c0.trailing"> 
because they have no common ancestor.  
Does the constraint or its anchors reference items in different view hierarchies?  
That's illegal.'

如何基于已经存在的textLabel为我的counterLabel添加约束? textLabel还不是ContentView的子视图吗?

1 个答案:

答案 0 :(得分:0)

您正在尝试使用内置的textLabel,我敢肯定init时尚不可用。尝试在layoutSubviews调用之后立即在super方法内执行布局代码。该方法可能需要评估几次,因此您应该检查是否已经布局好视图(例如couterLabel.superview != nil

它的外观如下:

final class CounterHeaderView: UITableViewHeaderFooterView {

    static let reuseIdentifier: String = String(describing: self)

    let counterLabel = UILabel()

    override func layoutSubviews() {
        super.layoutSubviews()

        if counterLabel.superview == nil {
            layout()
        }
    }

    func layout() {
        contentView.addSubview(counterLabel)
        counterLabel.translatesAutoresizingMaskIntoConstraints = false
        counterLabel.backgroundColor = .red
        if let textLabel = self.textLabel {
            counterLabel.leadingAnchor.constraint(equalTo: textLabel.trailingAnchor, constant: 6.0).isActive = true
            counterLabel.topAnchor.constraint(equalTo: textLabel.topAnchor).isActive = true
            counterLabel.heightAnchor.constraint(equalToConstant: 24.0).isActive = true
        }
    }
}