UITableViewCell高度与动态子视图swift

时间:2017-10-28 10:37:46

标签: ios swift uitableview

我有一个UITableView UITableViewCell有一个动态UILabel,它将根据我从数据库中获取的数据添加。

我使用

之类的东西
let testing = ["A", "B", "C", "D"] // This array is dynamic data
self.dictionaryTableView.estimatedRowHeight = 44
self.dictionaryTableView.rowHeight = UITableViewAutomaticDimension

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath)
    var y = 0
    for var i in 0..<self.testing.count {
        let lbl = UILabel(frame: CGRect(x: 0, y: y, width: 50, height: 25))
        lbl.text = self.testing[i]
        lbl.numberOfLines = 0
        cell.addSubview(lbl)
        y += 20       
    }
    return cell
}

UITableViewCell高度不会自动拉伸以显示所有内容单元格。请帮忙 这是结果 enter image description here

编辑我在UITableView cellForRowAtIndexPath中为uilabel添加了约束,约束正在运行(当我花费单元格高度时我就知道了),但是单元格高度没有自动拉伸

var bottomAnchor: NSLayoutYAxisAnchor = NSLayoutYAxisAnchor()
for var i in 0..<self.testing.count {
    let lbl = UILabel()
    lbl.text = self.testing[i]
    lbl.numberOfLines = 0
    lbl.translatesAutoresizingMaskIntoConstraints = false

    cell.addSubview(lbl)
    lbl.leftAnchor.constraint(equalTo: cell.leftAnchor, constant: 16).isActive = true
    lbl.widthAnchor.constraint(equalTo: cell.widthAnchor).isActive = true
    lbl.heightAnchor.constraint(equalToConstant: 25).isActive = true

    if i == 0 {
        lbl.topAnchor.constraint(equalTo: cell.topAnchor).isActive = true
    } else {
        lbl.topAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }
    bottomAnchor = lbl.bottomAnchor
}
return cell

非常感谢

4 个答案:

答案 0 :(得分:1)

使用此代码。

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
   return UITableViewAutomaticDimension
}

答案 1 :(得分:1)

您需要在实施中修复两件事:

  1. 在在tableView(_:, cellForRowAt:)中将其格式化之前,创建单元格的布局。

    出于效率原因,当用户滚动时,表视图重复重复使用相同的单元格。这就是为什么你使用这个奇怪的“出列”函数而不是简单地实例化一个新单元格。

    let cell = tableView.dequeueReusableCell(withIdentifier: "vocabCell", for: indexPath)
    

    将始终尝试返回刚刚滚出视图的已用单元格。只有当没有可用的再循环单元格时(例如,当将前几个单元格出列时),表格视图才会创建单元格的新实例。

    细胞的再循环是你永远tableView(_:, cellForRowAt:)内创建细胞布局的原因,例如通过添加标签。当重复使用单元格时,另外一个标签将添加到您之前添加的标签之上,当它再次被重复使用时,您将最终获得三个重叠标签等。

    这同样适用于约束。当您在tableView(_:, cellForRowAt:)中向单元格添加约束而不删除现有约束时,将在用户滚动时添加越来越多的约束,这很可能会导致严重的约束冲突。

    相反,在出列前设置单元格的布局。有几种方法可以实现这一目标:

    • 如果您在故事板中使用UITableViewController,则可以创建动态原型并直接在故事板中布置单元格。例如,您可以将标签拖到那里的原型单元格,并在自定义UITableViewCell子类中为它创建一个出口。

    • 您可以为您的单元格创建一个XIB文件,在Interface Builder中打开它并在那里创建您的布局。同样,您需要使用适当的出口创建一个UITableViewCell子类,并将其与您的XIB文件相关联。

    • 您可以创建一个UITableViewCell子类并纯粹在代码中设置布局,例如在单元格的初始化程序中。

  2. 您需要使用自动布局。

    如果您在Interface Builder中创建布局,则只需添加必要的约束,就可以了。如果您在代码中创建布局,则需要为要约束的所有视图将translatesAutoresizingMaskIntoConstraints属性设置为false,例如:

    lbl.translatesAutoresizingMaskIntoConstraints = false
    

    在您的特定布局中,您需要使用单元格contentView的相应边缘约束左侧,右侧,顶部和底部的标签。

    如果您不知道该怎么做,请阅读Apple的Auto Layout Guide。 (在Interface Builder中而不是在代码中执行此操作通常更好。)

    有关如何使用“UITableView中的自动布局以获取动态单元格布局和可变行高”的详细说明,可以找到here

答案 2 :(得分:1)

您可以使用UITableView部分呈现数据,而不是以编程方式添加视图。这是一个例子:

class ViewController: UITableViewController {

    private var dataSectionOne = ["Data 1", "Data 2"]
    // This can be your dynamic data. 
    // Once the data changed, called tableView.reloadData() to update the view.
    private var dataSectionTwo = ["A", "B", "C"] 

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 44
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return dataSectionOne.count
        } else if section == 1 {
            return dataSectionTwo.count
        }
        return 0
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        if indexPath.section == 0 {
            cell.textLabel?.text = dataSectionOne[indexPath.row]
        } else if indexPath.section == 1 {
            cell.textLabel?.text = dataSectionTwo[indexPath.row]
        }
        return cell
    }

}

结果:

Demo

答案 3 :(得分:0)

我找到了答案here

我使用以下代码向我的UITableViewCell底部添加了一个约束并且它正在工作,但我不知道这条线到底在做什么(我也不知道参数)

任何人都可以帮我解释一下这段代码

let bottomSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint(item: lbl, attribute: NSLayoutAttribute.bottomMargin, relatedBy: NSLayoutRelation.equal, toItem: cell.contentView, attribute: NSLayoutAttribute.bottomMargin, multiplier: 1, constant: -8)
cell.contentView.addConstraint(bottomSpaceConstraint)