ios - 如何创建高度由其标签高度决定的 UITableView header ?

标签 ios swift

我想在我的 tableView 中添加一个标题。此 header 包含 1 个 UILabel。标题高度应根据标签的行数计算。

在我的代码中,我在标签 <> 标题的所有边缘添加约束。这是我的尝试:

    //Add header to tableView
    header = UIView()
    header.backgroundColor = UIColor.yellowColor()
    tableView!.tableHeaderView = header

    //Create Label and add it to the header
    postBody = UILabel()
    postBody.text = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog."
    postBody.font = UIFont(name: "Lato-Regular", size: 16.0)
    postBody.numberOfLines = 0
    postBody.backgroundColor = FlatLime()
    header.addSubview(postBody)

    //Enable constraints for each item
    postBody.translatesAutoresizingMaskIntoConstraints = false
    header.translatesAutoresizingMaskIntoConstraints = false

    //Add constraints to the header and post body
    let postBodyLeadingConstraint = NSLayoutConstraint(item: postBody, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: header, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: 0)
    postBodyLeadingConstraint.active = true

    let postBodyTrailingConstraint = NSLayoutConstraint(item: postBody, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: header, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: 0)
    postBodyTrailingConstraint.active = true


    let postBodyTopConstraint = NSLayoutConstraint(item: postBody, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: header, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)
    postBodyTopConstraint.active = true


    let postBodyBottomConstraint = NSLayoutConstraint(item: postBody, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: header, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0)
    postBodyBottomConstraint.active = true


    //Calculate header size
    let size = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
    var frame = header.frame
    frame.size.height = size.height
    header.frame = frame
    tableView!.tableHeaderView = header
    header.layoutIfNeeded()

这是我的 table :

    let nib = UINib(nibName: "MessagesTableViewCell", bundle: nil)
    let nibSimple = UINib(nibName: "SimpleMessagesTableViewCell", bundle: nil)
    self.tableView!.registerNib(nib, forCellReuseIdentifier: "MessagesTableViewCell")
    self.tableView!.registerNib(nibSimple, forCellReuseIdentifier: "SimpleMessagesTableViewCell")
    self.tableView!.dataSource = self
    self.tableView!.delegate = self
    self.tableView!.rowHeight = UITableViewAutomaticDimension
    self.tableView!.estimatedRowHeight = 100.0
    self.tableView!.separatorStyle = UITableViewCellSeparatorStyle.None
    self.tableView!.separatorColor = UIColor(hex: 0xf5f5f5)
    self.tableView!.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)
    self.tableView!.clipsToBounds = true
    self.tableView!.allowsSelection = false
    self.tableView!.allowsMultipleSelection = false
    self.tableView!.keyboardDismissMode = .OnDrag

如您所见,标题没有考虑标签的高度(我做了 numberOfLines = 0)

Header does not auto-height

最佳答案

UILabel 利用 UIViewintrinsicContentSize() 告诉自动布局它们应该是什么大小。然而,对于多行标签,内在内容大小是不明确的; table 不知道它应该短而宽,高而窄,还是介于两者之间。

为了解决这个问题,UILabel 有一个名为 preferredMaxLayoutWidth 的属性。设置这个会告诉多行标签它最多应该是这个宽度,并允许 intrinsicContentSize() 找出并返回一个合适的高度来匹配。通过在您的示例中不设置 preferredMaxLayoutWidth,标签的宽度不受限制,因此会计算单行长文本的高度。

preferredMaxLayoutWidth 的唯一复杂之处在于,在自动布局为您计算出宽度之前,您通常不知道标签的宽度。出于这个原因,在 View Controller 子类中设置它的地方(它看起来像你的代码示例可能来自)在 viewDidLayoutSubviews 中:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    postBody.preferredMaxLayoutWidth = CGRectGetWidth(postBody.frame)
    // then update the table header view
    if let header = tableView?.tableHeaderView {
        header.frame.size.height = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
        tableView?.tableHeaderView = header
    }
}

显然,您需要为 postBody 标签添加一个属性才能使其正常工作。

如果您不在此处的 UIViewController 子类中,请告诉我,我将编辑我的答案。

关于ios - 如何创建高度由其标签高度决定的 UITableView header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36857284/

相关文章:

iphone - 继续使用 OpenUDID 粘贴板方法而不是 identifierForVendor 的风险

ios - 无法使用 firestore 数据库 swift 取消初始化

javascript - 如何在 objective-c 中实现 back4app.com 上的 javascript 代码

ios - UITableView分页,会显示无限加载

SwiftUI 表单编号输入

ios - 是否可以在 iOS 中自定义文本字段?

objective-c - 删除期间自定义单元格中的自动调整标签大小

ios - 如何从 Parse 中删除对象?

ios - Swift WebView 背景模式

ios - 是否可以在 Firebase 应用程序中安排登录?