在iOS Swift中动态调整UITableViewCell高度

时间:2016-04-06 18:29:29

标签: ios swift uitableview

我正在尝试创建一个UITableView,其单元格的高度根据显示的文本量进行调整。这似乎很简单,因为heightForRowAtIndexPath可用,我可以使用下面显示的代码获得UILabel所需的大小。但是,此方法在 cellForRowAtIndexPath之前称为,因此我无法根据单元格中的内容进行调整,这对我来说似乎是一个非常奇怪的选择。根据内容动态调整单元格高度的“最佳实践”方法是什么?

此外,为什么Apple在heightForRowAtIndexPath之后没有调用cellForRowAtIndexPath方法?

我在cellForRowAtIndexPath中使用以下内容来确定标签所需的高度,但我不知道如何将其移至heightForRowAtIndexPath,因为dequeReusableCellWithIdentifier无法调用方法(据我所知):

func getRequiredLabelHeight(label: UILabel, text: String, font: UIFont) -> CGFloat {
    label.numberOfLines = 0
    label.lineBreakMode = .ByWordWrapping
    label.font = font
    label.text = text
    label.sizeToFit()

    return label.frame.height

}

我也知道我希望以下是我的单元格高度,因为我希望单元格大小从初始大小(在1行标签上铰接)基于新标签大小(可以是任意长度)增加())

self.cellHeight = getRequiredLabelHeight(commentCell.commentTextLabel, text: allComments![indexPath.row].text, font: UIFont(name: "Avenir", size: 16.0)!) + commentCell.bounds.height - commentCell.commentTextLabel.bounds.height

谢谢!

修改 我的问题与调整标签大小无关。我提供的代码就是这样做的。问题是细胞高度不是恒定的;它根据内容在整个表格中有所不同,因此我不能使用静态tableview.rowHeight。由于我无法从cellForRowAtIndexPath调整单元格高度,因此我的内容不适合单元格。例如,这是我的cellForRowAtIndexPath(简而言之):

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let commentCell: CommentTableViewCell = tableView.dequeueReusableCellWithIdentifier("commentTableViewCell", forIndexPath: indexPath)
        as! CommentTableViewCell

    commentCell.commentTextLabel.textColor = Utils.hatchliTextDark
    commentCell.commentTextLabel.font = UIFont(name: "Avenir", size: 16)

    self.cellHeight = getRequiredLabelHeight(commentCell.commentTextLabel, text: allComments![indexPath.row].text, font: UIFont(name: "Avenir", size: 16.0)!) + commentCell.bounds.height - commentCell.commentTextLabel.bounds.height

    commentCell.commentTextLabel.frame = CGRectMake(commentCell.commentTextLabel.frame.origin.x, commentCell.commentTextLabel.frame.origin.y, commentCell.commentTextLabel.frame.width, self.cellHeight)
    commentCell.handleTextLabel.text = String(allComments![indexPath.row].creatorHandle)
    commentCell.votesTextLabel.text = String(allComments![indexPath.row].votes)
    commentCell.commentTextLabel.text = allComments![indexPath.row].text
    commentCell.setMargin()

    return commentCell

}

因此,如果UILabel的框架变大than tableview.rowHeight,它将不会出现。因此,需要根据heightForRowAtIndexPath(我假设)

逐个单元地调整行高

4 个答案:

答案 0 :(得分:2)

<强>解

我找到的解决方案有点粗糙,但我没有看到任何其他方式。基本上,除了要显示的文本字符串和字体属性之外,我知道我的UILabel宽度占用的屏幕比例。基于这些因素,我可以使用以下代码来确定需要UILabel的高度,并通过分解默认单元格和标签高度,可以在生成单元格之前找到我所需的单元格高度:

// width of string as a particular font in one line
func getStringSizeForFont(font: UIFont, myText: String) -> CGSize {
    let fontAttributes = [NSFontAttributeName: font]
    let size = (myText as NSString).sizeWithAttributes(fontAttributes)

    return size

}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    // get the string size
    let stringSizeAsText: CGSize = getStringSizeForFont(UIFont(name: "Avenir", size: 16.0)!, myText: allComments![indexPath.row].text)

    // label width and height are hardcoded here, but can easily be made dynamic based on the screen width
    // and the constant proportion of the width the UILabel will take up
    // example:
    // let labelWidth: CGFloat = UIScreen.mainScreen().bounds.width * widthProportion
    // originalLabelHeight can be hardcoded or made dynamic; I'm going to leave my hardcoded because I'll be leaving the height
    // the same across all devices

    let labelWidth: CGFloat = 259.0
    let originalLabelHeight: CGFloat = 20.5

    // the label can only hold its width worth of text, so we can get the ammount of lines from a specific string this way
    let labelLines: CGFloat = CGFloat(ceil(Float(stringSizeAsText.width/labelWidth)))

    // each line will approximately take up the original label's height
    let height =  tableView.rowHeight - originalLabelHeight + CGFloat(labelLines*stringSizeAsText.height)

    return height

}

答案 1 :(得分:1)

1)我认为对你这个案子的最佳选择是:

覆盖func tableView(tableView:UITableView,estimatedHeightForRowAtIndexPath indexPath:NSIndexPath) - &gt; CGFloat {         返回UITableViewAutomaticDimension     }

...并在“heightForRowAtIndexPath”中指示“return UITableViewAutomaticDimension”

2)如果计算高度,另一个选项是:

在“cellForRowAtIndexPath”中,您应该能够更改“self.tableView.rowHeight”的值。 如果TableView具有不同的nib,则此选项也很有用。

答案 2 :(得分:0)

调整表格视图的最佳选项动态单元格高度使用Autolayouts。

在白色UIView的底部设置标签的底部,并确保白色UIView具有左,右,顶部和底部约束:)

Same type of example is explained here programmatically....

答案 3 :(得分:-2)

嗯,我完成了本教程,一行代码帮助我调整了uitableview单元格内容的大小。

//=====
https://www.raywenderlich.com/129059/self-sizing-table-view-cells
//=====

添加

tableView.rowHeight = UITableViewAutomaticDimension

tableView.estimatedRowHeight = 140

在viewDidLoad()中并确保label / textview的行数为0