Ios 带自动尺寸标注的UITableView不';由于NSLayoutConstraint错误,无法动态增加大小
我正在创建一个自定义的Ios 带自动尺寸标注的UITableView不';由于NSLayoutConstraint错误,无法动态增加大小,ios,swift,uitableview,autolayout,nslayoutconstraint,Ios,Swift,Uitableview,Autolayout,Nslayoutconstraint,我正在创建一个自定义的UITableViewCell。现在,我只想让它在左边有一个ui按钮(checkButton),在按钮右边有两个ui标签(titleLabel和notesLabel) 基本上,它应该看起来像一个标准的UITableViewCell,带有一个图像和两个文本标签(但请不要告诉我仅仅重复使用一个标准单元格,因为出于各种原因,我不能这样做)。按钮应具有固定大小(16x16),并在单元格中垂直居中。这两个标签应换行并展开以适合其内容。我试图以编程的方式定义这个单元格,所以我创建了下面
UITableViewCell
。现在,我只想让它在左边有一个ui按钮(checkButton
),在按钮右边有两个ui标签(titleLabel
和notesLabel
)
基本上,它应该看起来像一个标准的UITableViewCell
,带有一个图像和两个文本标签(但请不要告诉我仅仅重复使用一个标准单元格,因为出于各种原因,我不能这样做)。按钮应具有固定大小(16x16),并在单元格中垂直居中。这两个标签应换行并展开以适合其内容。我试图以编程的方式定义这个单元格,所以我创建了下面的初始值设定项来定义约束
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.font = UIFont.systemFont(ofSize: 16)
titleLabel.lineBreakMode = .byWordWrapping
titleLabel.numberOfLines = 0
contentView.addSubview(titleLabel)
checkButton.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(checkButton)
notesLabel.translatesAutoresizingMaskIntoConstraints = false
notesLabel.font = UIFont.systemFont(ofSize: 13)
notesLabel.lineBreakMode = .byWordWrapping
notesLabel.numberOfLines = 0
contentView.addSubview(notesLabel)
addConstraint(NSLayoutConstraint(item: titleLabel,
attribute: .top,
relatedBy: .equal,
toItem: contentView,
attribute: .top,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .top,
relatedBy: .equal,
toItem: titleLabel,
attribute: .bottom,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: titleLabel,
attribute: .trailing,
relatedBy: .equal,
toItem: contentView,
attribute: .trailing,
multiplier: 1,
constant: -10))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .trailing,
relatedBy: .equal,
toItem: contentView,
attribute: .trailing,
multiplier: 1,
constant: -10))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .bottom,
relatedBy: .equal,
toItem: contentView,
attribute: .bottom,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .leading,
relatedBy: .equal,
toItem: contentView,
attribute: .leading,
multiplier: 1,
constant: 20))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .centerY,
relatedBy: .equal,
toItem: contentView,
attribute: .centerY,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .height,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 0,
constant: 16))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 0,
constant: 16))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .leading,
relatedBy: .equal,
toItem: checkButton,
attribute: .trailing,
multiplier: 1,
constant: 12))
addConstraint(NSLayoutConstraint(item: titleLabel,
attribute: .leading,
relatedBy: .equal,
toItem: checkButton,
attribute: .trailing,
multiplier: 1,
constant: 12))
}
当我运行这段代码时,它基本上按照预期工作,除了Xcode打印以下警告:[warning]仅警告一次:检测到约束模糊地表示tableview单元格内容视图的高度为零的情况。我们正在考虑非故意倒塌,并使用标准高度代替。
我通常会忽略这一点,但它似乎阻止了细胞扩展以适应其内容。例如,如果其中一个标签的内容足够扩展到3行,则仅显示第一行。我想要的行为是标签(扩展为单元格)展开以适应其内容。高度限制有什么不对吗?注意:请将标签和按钮添加到单元格中,而不是单元格的内容视图中。下面的代码将工作,请检查并让我知道在任何问题的情况下
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
addSubview(titleLabel)
addSubview(checkButton)
addSubview(notesLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.font = UIFont.systemFont(ofSize: 16)
titleLabel.lineBreakMode = .byWordWrapping
titleLabel.numberOfLines = 0
checkButton.translatesAutoresizingMaskIntoConstraints = false
notesLabel.translatesAutoresizingMaskIntoConstraints = false
notesLabel.font = UIFont.systemFont(ofSize: 13)
notesLabel.lineBreakMode = .byWordWrapping
notesLabel.numberOfLines = 0
addConstraint(NSLayoutConstraint(item: titleLabel,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .top,
relatedBy: .equal,
toItem: titleLabel,
attribute: .bottom,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: titleLabel,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: 1,
constant: -10))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: 1,
constant: -10))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .bottom,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1,
constant: 20))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .centerY,
relatedBy: .equal,
toItem: self,
attribute: .centerY,
multiplier: 1,
constant: 0))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .height,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 0,
constant: 16))
addConstraint(NSLayoutConstraint(item: checkButton,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 0,
constant: 16))
addConstraint(NSLayoutConstraint(item: notesLabel,
attribute: .leading,
relatedBy: .equal,
toItem: checkButton,
attribute: .trailing,
multiplier: 1,
constant: 12))
addConstraint(NSLayoutConstraint(item: titleLabel,
attribute: .leading,
relatedBy: .equal,
toItem: checkButton,
attribute: .trailing,
multiplier: 1,
constant: 12))
}
这是我的方法
private func setUp() {
self.selectionStyle = .none
self.contentView.backgroundColor = .white
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 16, height: 16))
button.setImage(UIImage(named: "arrow"), for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(button)
button.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 8.0).isActive = true
button.centerYAnchor.constraint(equalTo: self.contentView.centerYAnchor).isActive = true
button.widthAnchor.constraint(equalToConstant: button.frame.width).isActive = true
button.heightAnchor.constraint(equalToConstant: button.frame.height).isActive = true
let view = UIView()
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(view)
view.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 8.0).isActive = true
view.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: button.frame.width + 16.0).isActive = true
view.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: 8.0).isActive = true
view.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -8.0).isActive = true
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.numberOfLines = 0
view.addSubview(titleLabel)
titleLabel.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
notesLabel.translatesAutoresizingMaskIntoConstraints = false
notesLabel.numberOfLines = 0
view.addSubview(notesLabel)
notesLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8.0).isActive = true
notesLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
notesLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
notesLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
如果标签是多行动态高度,请使用以下选项启用自调整单元格大小
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 44.0
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
这就产生了
约束应添加到contentView。啊,谢谢!我现在可以停止拔头发了。如果你把它作为一个答案,我会接受的。谢谢你的回答!看起来这是可行的,但我更喜欢Sachin的方法,因为添加到内容视图可以在模式之间转换时提供漂亮的动画,等等。这很好,但我会提供估计行高的实际值。主要是因为滚动指示器不会在滚动时闪烁和调整大小。另外,提供一个具体的值更有意义,即单元格的估计值是估计的,并不会真正增加值。