当我使用几种不同的方式显示单元格时,UITableView 单元格中是否可以有不同的高度?

Is it possible to have differing heights in a UITableView Cell when I use several different ways of displaying the cell?(当我使用几种不同的方式显示单元格时,UITableView 单元格中是否可以有不同的高度?)

本文介绍了当我使用几种不同的方式显示单元格时,UITableView 单元格中是否可以有不同的高度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了几天时间试图解决这个问题,但似乎没有解决方案.我有一个非常基本的 UITableView 单元格,里面有两个标签.其中之一将是一条线,第二条将是多线.第二个将在高度上有所不同.这是我正在尝试生成的示例( UITableViewCells 内的 UIStackViews ):

I've spent several days trying to figure this out, but there doesn't seem to be a solution. I have a very basic UITableView cell with two labels in it. One of them will be one line, the second will be multiline. The second one will be varying in heights. Here is an example of what I'm trying to produce ( UIStackViews inside of UITableViewCells ) :

通过阅读数百篇 SO 帖子、数百篇博客、搜索 Apple 开发者网站,似乎有无数种方法可以编写此内容.在尝试了数百种不同的方式之后,我仍然无法像这样显示文本.我认为一些问题来自于我在一个 UITableView 中使用了 3 个不同的 UITableView 单元格变体.

From reading hundreds of SO posts, hundreds of blogs, scouring the Apple Developer sites, there seems to be an unlimited amount of ways one could write this. After having experimented with hundreds of different ways, I still can't manage to display the text like so. I think some of the trouble comes from the fact that I'm using 3 different UITableView cell variations in one UITableView.

这是我最近尝试的代码 cellForRowAtIndexPath :

Here is my code from my latest attempt cellForRowAtIndexPath :

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

    var cell : UITableViewCell!

    let (parent, isParentCell) = self.findParent(indexPath.row)

    if !isParentCell {

        let categories = ["words", "translation","commentary"]

        if categories[parent] == "words" {

            cell = tableView.dequeueReusableCellWithIdentifier(childWordsCellIdentifier, forIndexPath: indexPath) as UITableViewCell

            // Reset content
            for subview in cell.contentView.subviews {
                subview.removeFromSuperview()
            }
            cell.prepareForReuse()


            let words                   = self.page.valueForKey("words")!.allObjects as! [Word]
            let wordsInOrder            = words.sort({Int($0.order!) < Int($1.order!) })
            let word                    = wordsInOrder[indexPath.row - 1]

            let labelWidth              = (self.view.frame.width - 80) / 2


            let wordLabel               = UILabel(frame: CGRectZero)
            wordLabel.text              = word.valueForKey("sanskrit") as? String
            wordLabel.font              = UIFont(name: "EuphemiaUCAS-Bold", size: 16)
            wordLabel.numberOfLines     = 0
            wordLabel.translatesAutoresizingMaskIntoConstraints = false
            wordLabel.layer.borderColor = UIColor.greenColor().CGColor
            wordLabel.layer.borderWidth = 1.0
            let widthWordConstraint = wordLabel.widthAnchor.constraintEqualToConstant(labelWidth)
            widthWordConstraint.priority = 300
            widthWordConstraint.active = true

            let englishWordLabel           = UILabel(frame: CGRectZero)
            englishWordLabel.text          = "Foobar don't want to play my game with my anymore."
            englishWordLabel.font          = UIFont(name: "STHeitiTC-Light", size: 16)
            englishWordLabel.numberOfLines = 0
            englishWordLabel.preferredMaxLayoutWidth = labelWidth
            englishWordLabel.translatesAutoresizingMaskIntoConstraints = false
            let englishWordConstraint = englishWordLabel.widthAnchor.constraintEqualToConstant(labelWidth)
            englishWordConstraint.priority = 300
            englishWordConstraint.active = true
            englishWordLabel.layer.borderColor = UIColor.blueColor().CGColor
            englishWordLabel.layer.borderWidth = 1.0

            let stackView = UIStackView()
            stackView.axis = .Horizontal
            stackView.distribution = .FillProportionally
            stackView.alignment = .FirstBaseline
            stackView.spacing = 15
            stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
            stackView.layoutMarginsRelativeArrangement = true

            stackView.addArrangedSubview(wordLabel)
            stackView.addArrangedSubview(englishWordLabel)

            stackView.translatesAutoresizingMaskIntoConstraints = false

            englishWordLabel.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
            englishWordLabel.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true


            cell.contentView.addSubview(stackView)

            cell.contentView.layoutIfNeeded()


        } else {

            cell = tableView.dequeueReusableCellWithIdentifier(childCellIdentifier, forIndexPath: indexPath) as UITableViewCell

            // Reset content
            cell.textLabel!.text = ""
            for subview in cell.contentView.subviews {
                subview.removeFromSuperview()
            }
            cell.prepareForReuse()

            cell.textLabel!.text        = self.page.valueForKey(categories[parent]) as? String
            cell.textLabel!.textColor   = UIColor(red: 35/255.0, green: 31/255.0, blue: 32/255.0, alpha: 1.0)
            cell.textLabel!.font        = UIFont(name: "STHeitiTC-Light", size: 16)
        }
    }
    else {
        // Parent
        cell = tableView.dequeueReusableCellWithIdentifier(parentCellIdentifier, forIndexPath: indexPath)
        cell.textLabel!.text        = self.dataSource[parent].title
        cell.textLabel!.textColor   = UIColor(red: 66/255.0, green: 116/255.0, blue: 185/255.0, alpha: 1.0)
        cell.textLabel!.font        = UIFont(name: "STHeitiTC-Light", size: 20)
    }

    cell.selectionStyle                                       = .None
    cell.textLabel!.translatesAutoresizingMaskIntoConstraints = false
    cell.textLabel!.numberOfLines                             = 0
    cell.textLabel!.lineBreakMode = .ByWordWrapping

    return cell
}

产生这个:

推荐答案

表格视图单元格的高度由表格根据rowHeight属性决定,或者根据可选 func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) ->来自表视图委托的 CGFloat.

The height of a table view cell is decided by the table based on the rowHeight property, or on the return value of optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat from the table view delegate.

程序员可能通过其 frame 属性为 UITableViewCell 设置的高度被忽略!

The height that may be set by the programmer for the UITableViewCell through its frame property is ignored!

因此,您需要以编程方式计算出每个单元格的所需高度.然后你需要实现 optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) ->每个单元格的表格视图委托中的 CGFloat.

Hence you need to figure out the desired height of each cell programatically. Then you need to implement optional func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat from the table view delegate for each of the cells.

如果在显示表格视图时单元格的大小发生变化,您需要:

If the size of a cell changes while the table view is displayed, you need to either:

  • 使用 UITableView 中的 reloadData() 重新加载表格,或
  • 使用 UITableView 中的 func reloadRowsAtIndexPaths(_ indexPaths: [NSIndexPath], withRowAnimation animation: UITableViewRowAnimation) 更新单元格.
  • reload the table with reloadData() from UITableView, or
  • update the cell with func reloadRowsAtIndexPaths(_ indexPaths: [NSIndexPath], withRowAnimation animation: UITableViewRowAnimation) from UITableView.

编辑

实际上,由于您在视图中使用了约束,它应该可以在不使用 `` 的情况下工作.

Actually since you are using constraints in you view it should work without using ``.

尝试将 if categories[parent] == "words" { .. } 中的代码替换为:

Try to replace the code in if categories[parent] == "words" { .. } with:

        cell = tableView.dequeueReusableCellWithIdentifier(childWordsCellIdentifier, forIndexPath: indexPath) as UITableViewCell

        // Reset content
        for subview in cell.contentView.subviews {
            subview.removeFromSuperview()
        }
        cell.prepareForReuse()


        let words                   = self.page.valueForKey("words")!.allObjects as! [Word]
        let wordsInOrder            = words.sort({Int($0.order!) < Int($1.order!) })
        let word                    = wordsInOrder[indexPath.row - 1]


        let wordLabel               = UILabel(frame: CGRectZero)
        wordLabel.text              = word.valueForKey("sanskrit") as? String
        wordLabel.font              = UIFont(name: "EuphemiaUCAS-Bold", size: 16)
        wordLabel.numberOfLines     = 0
        wordLabel.translatesAutoresizingMaskIntoConstraints = false
        wordLabel.layer.borderColor = UIColor.greenColor().CGColor
        wordLabel.layer.borderWidth = 1.0

        let englishWordLabel           = UILabel(frame: CGRectZero)
        englishWordLabel.text          = "Foobar don't want to play my game with my anymore."
        englishWordLabel.font          = UIFont(name: "STHeitiTC-Light", size: 16)
        englishWordLabel.numberOfLines = 0

        let stackView = UIStackView()
        stackView.axis = .Horizontal
        stackView.distribution = .FillProportionally
        stackView.alignment = .Fill  // EDIT
        stackView.spacing = 15
        stackView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
        stackView.layoutMarginsRelativeArrangement = true

        stackView.addArrangedSubview(wordLabel)
        stackView.addArrangedSubview(englishWordLabel)

        stackView.translatesAutoresizingMaskIntoConstraints = false

        cell.contentView.addSubview(stackView)
        cell.contentView.leadingAnchor.constraintEqualToAnchor(stackView.leadingAnchor).active = true
        cell.contentView.topAnchor.constraintEqualToAnchor(stackView.topAnchor).active = true
        cell.contentView.trailingAnchor.constraintEqualToAnchor(stackView.trailingAnchor).active = true
        cell.contentView.bottomAnchor.constraintEqualToAnchor(stackView.bottomAnchor).active = true

        cell.contentView.layoutIfNeeded()

另外,我会为此任务使用两个不同的单元格类,而不是删除 contentView 中的视图.

Also I would have used two different cells classes for this task rather than removing the views in the contentView.

请告诉我进展如何!

这篇关于当我使用几种不同的方式显示单元格时,UITableView 单元格中是否可以有不同的高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:当我使用几种不同的方式显示单元格时,UITableView 单元格中是否可以有不同的高度?

基础教程推荐