【发布时间】:2018-12-04 20:04:33
【问题描述】:
背景
我使用 purelayout 以编程方式创建我的 UITableViewCells,遵循here 的说明,它基本上说明您必须在单元格上设置顶部/底部约束,然后使用
self.tableView.rowHeight = UITableViewAutomaticDimension;
正确处理:
问题
一切正常,除非我在 tableView 中插入新行。我得到这个效果:https://youtu.be/eTGWsxwDAdk
解释一下:只要我点击一个提示单元格,表格就会插入一个司机提示行。但是您会注意到,当我刷新该部分(通过单击提示框)时,所有单元格的高度都会莫名其妙地增加,但是当我再次单击提示框时,它们会恢复到正常高度 这是用这段代码完成的
self.tableView.beginUpdates()
self.tableView.reloadSections(IndexSet(integer:1), with: .automatic)
self.tableView.endUpdates()
这是cellfor row的实现
// init table
self.tableView.register(OrderChargeTableViewCell.self,
forCellReuseIdentifier: OrderChargeTableViewCell.regularCellIdentifier)
self.tableView.register(OrderChargeTableViewCell.self,
forCellReuseIdentifier: OrderChargeTableViewCell.boldCellIdentifier)
self.tableView.estimatedRowHeight = 25
self.tableView.rowHeight = UITableViewAutomaticDimension
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: OrderChargeTableViewCell?
if (indexPath.row == filteredModel.count-1) {
cell = tableView.dequeueReusableCell(withIdentifier: OrderChargeTableViewCell.boldCellIdentifier,
for: indexPath) as? OrderChargeTableViewCell
} else if (indexPath.row < filteredModel.count) {
cell = tableView.dequeueReusableCell(withIdentifier: OrderChargeTableViewCell.regularCellIdentifier,
for: indexPath) as? OrderChargeTableViewCell
}
// add data to cell labels
return cell!
}
这是 UITableViewCell 本身的代码:
最终类 OrderChargeTableViewCell: UITableViewCell {
// MARK: - init
static let boldCellIdentifier = "TTOrderDetailBoldTableViewCell"
static let regularCellIdentifier = "TTOrderDetailRegularTableViewCell"
private var didSetupConstraints = false
..
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
self.keyLabel = TTRLabel()
self.valueLabel = TTRLabel()
if (reuseIdentifier == OrderChargeTableViewCell.regularCellIdentifier) {
self.isCellStyleBold = false
} else if (reuseIdentifier == OrderChargeTableViewCell.boldCellIdentifier) {
self.isCellStyleBold = true
} else {
self.isCellStyleBold = false
assertionFailure( "Attempt to create an OrderCharge cell with the wrong cell identifier: \(String(describing: reuseIdentifier))")
}
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(keyLabel)
contentView.addSubview(valueLabel)
}
override func updateConstraints()
{
if !didSetupConstraints {
if (isCellStyleBold) {
self.applyBoldFormatting()
} else {
self.applyRegularFormatting()
}
didSetupConstraints = true
}
super.updateConstraints()
}
public func applyBoldFormatting() {
keyLabel.font = .ttrSubTitle
valueLabel.font = .ttrBody
keyLabel.autoPinEdge(.leading, to: .leading, of: contentView, withOffset: 15)
keyLabel.autoAlignAxis(.vertical, toSameAxisOf: contentView)
keyLabel.autoPinEdge(.top, to: .top, of: contentView, withOffset: 8)
keyLabel.autoPinEdge(.bottom, to: .bottom, of: contentView, withOffset: -8)
valueLabel.autoPinEdge(.trailing, to: .trailing, of: contentView, withOffset: -15)
valueLabel.autoAlignAxis(.baseline, toSameAxisOf: keyLabel)
}
public func applyRegularFormatting() {
keyLabel.font = .ttrCaptions
valueLabel.font = TTRFont.Style.standard(.h3).value
keyLabel.autoPinEdge(.leading, to: .leading, of: contentView, withOffset: 15)
keyLabel.autoAlignAxis(.vertical, toSameAxisOf: contentView)
keyLabel.autoPinEdge(.top, to: .top, of: contentView, withOffset: 6)
keyLabel.autoPinEdge(.bottom, to: .bottom, of: contentView, withOffset: -4)
valueLabel.autoPinEdge(.trailing, to: .trailing, of: contentView, withOffset: -15)
valueLabel.autoAlignAxis(.baseline, toSameAxisOf: keyLabel)
}
【问题讨论】:
-
你能把你的代码减少到能证明问题的最低限度吗?我刚刚做了一个快速测试,在自动布局处理行高时插入/删除行没有问题。
-
嘿阿布德,当我遇到这样的问题时,我会尝试将复杂性降低到最低限度,这意味着删除设置字体,留在与内容对齐的标签上,并带有狐狸边距。比你可以在 init 方法中设置的约束,比你不需要存储这个 didSrtupConstraint 的东西,当你有最小的僵硬时,再试一次。 Xcode 控制台会说什么吗?打破约束?
-
ahhh 并尝试在 awakeFromNib 函数中设置单元格,看看是否有帮助:)
-
@BjörnRo 事实上我需要设置
didSrtupConstraint的东西,这是为了确保我不会多次应用约束。来自this SO answer:If you're adding constraints in code, you should do this once from within the updateConstraints method of your UITableViewCell subclass. Note that updateConstraints may be called more than once, so to avoid adding the same constraints more than once,.. -
.. make sure to wrap your constraint-adding code within updateConstraints in a check for a boolean property such as didSetupConstraints (which you set to YES after you run your constraint-adding code once). On the other hand, if you have code that updates existing constraints (such as adjusting the constant property on some constraints), place this in updateConstraints but outside of the check for didSetupConstraints so it can run every time the method is called.
标签: ios swift uitableview nslayoutconstraint