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

时间:2017-08-14 18:30:57

标签: ios swift3

我有一个视图控制器,它使用一个名为searchCell的自定义单元格来引入内容,我想知道如何获取标签lblLeft的高度并在tableView中使用它(_ tableView:UITableView,heightForRowAt indexPath:IndexPath) - > CGFloat函数返回标签的高度。我在主视图控制器中使用的代码:

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 个答案:

答案 0 :(得分:1)

第一种方式使用自动尺寸

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

enter image description here

确保在情节提要中将标签行设置为res.append(temp[:])

现在在控制器类中执行此操作 - :

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
    }

计算estimatedHeightForLabel的另一种方法 - :

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

2)使用NSString的 public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{ return UITableViewAutomaticDimension } 方法从标签中找到细胞的确切高度 - :

表格视图功能 - :

boundingRect

记住 - :

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

2)对于多行标签使用选项为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 }

<强> CustomCellClass - :

.usesLineFragmentOrigin

答案 1 :(得分:0)

我使用自定义扩展来计算NSAttributedString的高度。 &#34; containerWidth&#34;将是您的标签的最大宽度,这很可能是您的单元格的contentView.bounds.size.width。

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

}

一个&#34;技巧&#34;是在cellForRowAtIndexPath之前调用heightForRowAtIndexPath。您需要创建一个占位符单元格并保留对它的引用。然后你做这样的事情:

// 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自动为您设置单元格的高度。这可能是更好的选择。