Swift 重新扩展时约束被破坏 Table 视图
Swift Constraint Broken When Re-Expanding Table View
所以我有一个包含部分和行的 2 深度 table 视图。当我第一次展开 table 视图时,一切都已经很好了,但是如果我在第 2 次、第 3 次、... 展开它或在部分展开时滚动,那么行部分的左约束坏了,详情请看下图:
Please see this for details
这是我第 3 次扩充版块。如您所见,有 2 行打破了左约束。这是我的代码:
func configureCell(data: FirstDepth) {
self.firstDepthData = data
self.firstDepthLabel.text = data.name
self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 20)
}
func configureSecondCell(data: SecondDepth) {
self.secondDepthData = data
self.firstDepthLabel.text = data.name
self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 50)
}
因此 table 视图将为部分调用 configureCell,为行调用 configureSecondCell,我读到这可能是因为重新初始化约束,但如何只更新常量?
如果需要,这是我的 table 视图单元格代码:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CellFirstDepth.id, for: indexPath) as! CellFirstDepth
if let firstDepthData = self.firstDepthData {
if indexPath.row == 0 {
// Call Cell for sections
cell.configureCell(data: firstDepthData[indexPath.section])
} else {
// Call Cell for rows
cell.configureSecondCell(data: firstDepthData[indexPath.section].child[indexPath.row - 1])
}
}
return cell
}
这是我的 centerY 函数,只是一个使元素中心位于 Y 轴的代码,并将锚点添加到 left/right:
func centerY(inView view: UIView, leftAnchor: NSLayoutXAxisAnchor? = nil, rightAnchor: NSLayoutXAxisAnchor? = nil, paddingLeft: CGFloat? = nil, paddingRight: CGFloat? = nil, constant: CGFloat? = 0) {
translatesAutoresizingMaskIntoConstraints = false
centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: constant!).isActive = true
if let leftAnchor = leftAnchor, let paddingLeft = paddingLeft {
self.leftAnchor.constraint(equalTo: leftAnchor, constant: paddingLeft).isActive = true
} else if let rightAnchor = rightAnchor, let paddingRight = paddingRight {
self.rightAnchor.constraint(equalTo: rightAnchor, constant: -paddingRight).isActive = true
}
}
您没有向我们展示您的 .centerY(...)
函数的作用,但可以很安全地猜测问题所在。
看起来您正在添加一个常数为 20
的 .leftAnchor
约束,然后该单元格被重新使用并且您正在添加另一个 .leftAnchor
常数为 50
.
的约束
您需要编辑单元格代码以使用 单个 约束,并更新其 .constant
属性,而不是添加多个约束。
编辑
稍微搜索一下,您可以找到许多完整的示例,但这里是大体思路。
在您的单元格 class 中,添加此变量 属性:
var labelLeftConstraint: NSLayoutConstraint!
然后,在您的单元格 class 初始化中,创建该约束:
labelLeftConstraint = self.firstDepthLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0)
labelLeftConstraint.isActive = true
然后,像这样更改 configure
函数:
func configureCell(data: FirstDepth) {
self.firstDepthData = data
self.firstDepthLabel.text = data.name
labelLeftConstraint.constant = 20
//self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 20)
}
func configureSecondCell(data: SecondDepth) {
self.secondDepthData = data
self.firstDepthLabel.text = data.name
labelLeftConstraint.constant = 50
//self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 50)
}
现在您将只有一个 单个 约束,并且您的代码将设置它的 .constant
而不是一遍又一遍地创建它(这就是导致问题的原因).
所以我有一个包含部分和行的 2 深度 table 视图。当我第一次展开 table 视图时,一切都已经很好了,但是如果我在第 2 次、第 3 次、... 展开它或在部分展开时滚动,那么行部分的左约束坏了,详情请看下图:
Please see this for details
这是我第 3 次扩充版块。如您所见,有 2 行打破了左约束。这是我的代码:
func configureCell(data: FirstDepth) {
self.firstDepthData = data
self.firstDepthLabel.text = data.name
self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 20)
}
func configureSecondCell(data: SecondDepth) {
self.secondDepthData = data
self.firstDepthLabel.text = data.name
self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 50)
}
因此 table 视图将为部分调用 configureCell,为行调用 configureSecondCell,我读到这可能是因为重新初始化约束,但如何只更新常量?
如果需要,这是我的 table 视图单元格代码:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: CellFirstDepth.id, for: indexPath) as! CellFirstDepth
if let firstDepthData = self.firstDepthData {
if indexPath.row == 0 {
// Call Cell for sections
cell.configureCell(data: firstDepthData[indexPath.section])
} else {
// Call Cell for rows
cell.configureSecondCell(data: firstDepthData[indexPath.section].child[indexPath.row - 1])
}
}
return cell
}
这是我的 centerY 函数,只是一个使元素中心位于 Y 轴的代码,并将锚点添加到 left/right:
func centerY(inView view: UIView, leftAnchor: NSLayoutXAxisAnchor? = nil, rightAnchor: NSLayoutXAxisAnchor? = nil, paddingLeft: CGFloat? = nil, paddingRight: CGFloat? = nil, constant: CGFloat? = 0) {
translatesAutoresizingMaskIntoConstraints = false
centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: constant!).isActive = true
if let leftAnchor = leftAnchor, let paddingLeft = paddingLeft {
self.leftAnchor.constraint(equalTo: leftAnchor, constant: paddingLeft).isActive = true
} else if let rightAnchor = rightAnchor, let paddingRight = paddingRight {
self.rightAnchor.constraint(equalTo: rightAnchor, constant: -paddingRight).isActive = true
}
}
您没有向我们展示您的 .centerY(...)
函数的作用,但可以很安全地猜测问题所在。
看起来您正在添加一个常数为 20
的 .leftAnchor
约束,然后该单元格被重新使用并且您正在添加另一个 .leftAnchor
常数为 50
.
您需要编辑单元格代码以使用 单个 约束,并更新其 .constant
属性,而不是添加多个约束。
编辑
稍微搜索一下,您可以找到许多完整的示例,但这里是大体思路。
在您的单元格 class 中,添加此变量 属性:
var labelLeftConstraint: NSLayoutConstraint!
然后,在您的单元格 class 初始化中,创建该约束:
labelLeftConstraint = self.firstDepthLabel.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0)
labelLeftConstraint.isActive = true
然后,像这样更改 configure
函数:
func configureCell(data: FirstDepth) {
self.firstDepthData = data
self.firstDepthLabel.text = data.name
labelLeftConstraint.constant = 20
//self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 20)
}
func configureSecondCell(data: SecondDepth) {
self.secondDepthData = data
self.firstDepthLabel.text = data.name
labelLeftConstraint.constant = 50
//self.firstDepthLabel.centerY(inView: contentView, leftAnchor: contentView.leftAnchor, paddingLeft: 50)
}
现在您将只有一个 单个 约束,并且您的代码将设置它的 .constant
而不是一遍又一遍地创建它(这就是导致问题的原因).