当前位置: 首页 > 知识库问答 >
问题:

获取自定义单元格中标签的高度,以用于主视图控制器中的heightForRowAt

司寇山
2023-03-14

我有一个视图控制器,它使用一个名为searchCell的自定义单元格来引入内容,我想知道如何获得标签lblLeft的高度并在tableView中使用它(_tableView:UITableView,heightForRowAt-indexPath:indexPath)-

func tableView(_ tableView: UITableView, cellForRowAt indexPath: 
    IndexPath) -> UITableViewCell {
    if searchMode == searching {
        let cell: MHSearchCell = tableView.dequeueReusableCell(withIdentifier: 
        MHSearchCell.ReusableIdentifier()) as! MHSearchCell

        cell.helper = helpers[indexPath.row]
        cell.delegate = self

        return cell
  }
}

在我的MHSearchCell中创建标签的代码的一部分,标签在这里作为IBOutlet连接:

lblLeft.text = ""

        if let expertiseCount = helper.expertise {

            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = 5
            paragraphStyle.lineBreakMode = .byWordWrapping
            paragraphStyle.alignment = NSTextAlignment.center
            lblLeft.numberOfLines = 0

            let finalString = expertiseCount.map({$0.name!}).joined(separator: "   \u{00B7}   ")
            let finalAttributedString = NSMutableAttributedString(string: finalString, attributes: [NSParagraphStyleAttributeName:paragraphStyle])
            lblLeft.attributedText = finalAttributedString
        }

共有2个答案

乐正秦斩
2023-03-14

我使用自定义扩展来计算 NS 属性字符串的高度。“容器宽度”将是标签的最大宽度,这很可能是单元格的宽度。

extension NSAttributedString {

func height(containerWidth: CGFloat) -> CGFloat {
    let rect = self.boundingRect(with: CGSize.init(width: containerWidth, height: CGFloat.greatestFiniteMagnitude), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil)
    return ceil(rect.size.height)
}

func width(containerHeight: CGFloat) -> CGFloat {
    let rect = self.boundingRect(with: CGSize.init(width: CGFloat.greatestFiniteMagnitude, height: containerHeight), options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil)
    return ceil(rect.size.width)
}

}

一个“技巧”是heightForRowAtIndexPath在cellForRowAtIndexPath之前被调用。您需要创建一个占位符单元格并保存对它的引用。然后你这样做:

// Init this once and early
var searchCellPlaceholder = SearchCell() // Use whatever the default initializer is 

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let object = data[indexPath.row]
    // Keep reusing this cell and populate it with the new object text, use the configure method in cellForRowAtIndex too.
    configureCell(cell: searchCellPlaceholder object: object)
    // Get the height of the label after the text was applied
    let height = searchCell.label.height(containerWidth: serachCell.contentView.bounds.size.width)

    return height
}

您不想在heightForRowAtIndexPath中初始化占位符单元格,因为每次调用一个对象时初始化它会真正降低您的性能。这就是为什么您从一开始就初始化它并继续重用它。

//

如果您使用的是自动布局,还可以查找如何让 UITableView 自动为您设置单元格的高度。这可能是一个更好的选择。

梁兴修
2023-03-14

第一种方法使用自动标注

1)在标签上应用适当的约束检查下图。

确保在故事板中将标签行设置为< code>0。

现在在控制器类中执行以下操作-

//MArk-: ViewDidLoad
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        yourTableView.estimatedRowHeight = 142.0 // Default cell height from storyboard

        yourTableView.rowHeight = UITableViewAutomaticDimension
    }

表格功能:

 public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
 return UITableViewAutomaticDimension
    }

另一种计算估计值的方法::

1) 如上所述,对标签应用相同的约束

2)使用NSString的边界曲线方法从标签中查找单元格的确切高度 - :

表视图功能-:

extension ViewController : UITableViewDelegate,UITableViewDataSource{
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return value.count
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? testingCell
        cell?.textlabel.text = value[indexPath.row]
        return cell!
    }

    // Number of sections in table

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }// Default is 1 if not implemented

    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
        let text = value[indexPath.row]
        let estimatedheight = calculateEstimatedHeight(text: text)
        return estimatedheight.height
    }

    func calculateEstimatedHeight(text:String) -> CGRect{
        let size = CGSize(width: view.frame.width, height: 1000)
        let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
        let attribute = [NSFontAttributeName:UIFont.systemFont(ofSize: 17)]
        let estimatedHeight = NSString(string: text).boundingRect(with: size, options: options, attributes: attribute, context: nil)
        return estimatedHeight
    }

记住:

1)提供与标签相同的字体大小。

2) 对于多行标签,请使用.usesLineFragmentOrigin选项。

CustomCellClass:

import UIKit

class testingCell: UITableViewCell {

    @IBOutlet weak var textlabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}
 类似资料:
  • 我从CoreData中获取对象,如下所示 并显示它: 如何在 中获得单元格的正确高度以返回它

  • 场景- > TableView高度是使用纵横比相对于superview的高度动态设置的。 TableViewCell的高度是根据表格视图的高度计算的: 问题 - 最初在委托方法中没有正确计算表格视图高度。但在滚动单元格后正确计算。 尝试的解决方案: 在视图中重新加载。 调用 在单元格中进行. 有什么方法可以正确计算出这个表格的高度吗?

  • 我正在尝试让我的表视图单元格根据单元格内的内容调整其高度。 它似乎在工作,因为单元格有不同的高度,但我无法正确显示文本。 表视图和原型单元格是用故事板创建的,我有一个自定义的单元格类链接到我的原型单元格。在我的原型电池中,我有三个标签;标题标签、日期标签和包含动态文本数据的标签。在情节提要的属性检查器中,动态文本数据标签行号设置为0,换行符设置为“换行”。 当我运行应用程序时,单元格高度都不同,因

  • 我按照本教程创建了一个自定义。xib,我计划在表格视图的单元格中使用它: https://medium.com/@brianclouser/swift-3-creating-a-custom-view-from-a-xib-ecdfe5b3a960 以下是我创建的 .xib 类: 以前,我在情节提要中创建我的表视图单元格,但我已经意识到我想要一个更灵活的视图,以便我可以在应用的不同部分使用它,所以

  • 我有一个由几个标签控件组成的自定义控件:日期、标题、文本等,控件有fxml文件和一个控制器。我想将此控件用作ListView的单元格。我创建了一个自定义列表单元格 但我不确定这是一个正确的做法。我的应用程序中的ListView可能有数千个项目。根据我的理解,在创建图形节点之前,每次单元格更新都必须加载fxml、进行解析和其他操作。有没有更好的办法来解决这个问题?

  • 我有一个带有几个IBOutlet的自定义单元格类。我已经将类添加到故事板。我已经连接了所有的出口。我的cellForRowAtIndexPath函数如下所示: 这是我的自定义单元格类: 当我运行应用程序时,我的所有手机都是空的。我已注销,它包含所有正确的字符串。我还尝试了将一个实际字符串与标签相等,这会产生相同的结果。 我错过了什么?感谢任何帮助。