UITableViewCell高度动态子视图swift

问题描述:

我有一个UITableViewUITableViewCell有一个动态的UILabel这将根据我从数据库中获得的数据添加。UITableViewCell高度动态子视图swift

我使用类似

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,约束正在努力(我知道,当我花费了单元格高度),但细胞高度不全自动STRETCH时出

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 

非常感谢

+0

为什么要添加多个标签? 我的意思是你可以插入下一行字符 – SPatel

+0

@ user3783161循环里面cellForRowAt是不是一个好主意,你可以添加标签,故事板的意见。你有没有使用你的疑问? –

+0

https://*.com/a/30300870/8779236看这回答 –

我找到了答案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) 

使用此代码。

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

1.不需要大于或等于标签高度的限制。 2.这些并不是所有必要的步骤。 – FreeNickname

+0

这已经过时,因为问题中的代码示例已经设置了'self.dictionaryTableView.rowHeight = UITableViewAutomaticDimension'。 – Mischa

+0

我已经试过但没有任何工作 – user3783161

还有,你需要在你的实现来解决两件事情:

  1. 创建你的tableView(_:, cellForRowAt:)出队它的布局。

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

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

    将始终尝试返回刚刚滚动出视图的已用单元。只有当没有可用的循环单元时(例如,当出现第一对单元格时),表格视图将创建单元格的新实例。

    细胞回收是你为什么应该从不tableView(_:, cellForRowAt:)内创建你的细胞布局的原因,例如通过添加标签。当单元格被重新使用时,另一个标签将被添加到您之前添加的标签的顶部,当它再次被重新使用时,您将最终得到三个重叠的标签等。

    同样适用于约束。如果在不删除现有约束的情况下向tableView(_:, cellForRowAt:)中的某个单元添加约束,则在用户滚动时会添加越来越多的约束,这很可能导致严重的约束冲突。

    取而代之,在之前设置您的单元格的布局。有几种方法来实现这一目标:

    • 如果使用UITableViewController故事板里面,你可以创建动态原型并直接在故事板铺陈细胞。例如,您可以将标签拖放到原型单元格中,并在自定义子类中为其创建出口。

    • 您可以为您的单元格创建XIB文件,在Interface Builder中打开它并在其中创建布局。再次,您需要创建一个带有适当插座的UITableViewCell子类并将其与您的XIB文件相关联。

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

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

    如果您在Interface Builder中创建布局,只需添加必要的约束条件即可。如果您在代码中创建您的布局,您需要将translatesAutoresizingMaskIntoConstraints属性设置为false为您要限制所有的意见,例如:

    lbl.translatesAutoresizingMaskIntoConstraints = false 
    

    在您的特定布局,则需要在左边来约束标签,右侧,顶部和底部与你的细胞的相应边缘contentView

    如果您不知道如何操作,请阅读Apple的Auto Layout Guide。 (这通常是一个更好的主意,在界面生成器,而不是代码来做到这一点。)如何“在UITableView的自动布局动态单元布局&可变行高度”使用

    非常详细的介绍,可以发现here

+0

我添加了约束(请参阅编辑),但不工作,有什么问题 – user3783161

+1

在我的代码中有一些其他错误,我一开始就忽略了。我更新了我的答案,并添加了有关如何解决此问题的详细说明。 – Mischa

+0

感谢您的详细信息,只是有一个问题。如果我在出队之前设置单元格布局,如何创建动态UILabel原因我不知道需要使用多少个标签 – user3783161

您可以使用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

+0

感谢您的建议。我的表格视图有动态部分,每个部分都有我想用UILabel存档的数据 – user3783161