我有一个简单的UITableViewCell
子类,其中有一个titleLabel属性(单元格具有更多视图,但是为了显示问题,我只会做一个标签,因为它也会坏掉)。
这是我的标签代码:
self.titleLabel = UILabel(frame: .zero)
self.titleLabel.numberOfLines = 0
self.titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
self.titleLabel.textColor = UIColor.white
self.titleLabel.adjustsFontSizeToFitWidth = false
self.titleLabel.textAlignment = .left
self.titleLabel.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.titleLabel)
self.titleLabel.topAnchor.constraint(equalTo: self.artworkImageView.topAnchor).isActive = true
self.titleLabel.leftAnchor.constraint(equalTo: self.artworkImageView.rightAnchor, constant: 10.0).isActive = true
self.titleLabel.rightAnchor.constraint(equalTo: self.contentView.rightAnchor, constant: -10.0).isActive = true
self.titleLabel.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true
我也这样设置UITableView
:
self.tableView.rowHeight = UITableView.automaticDimension
self.tableView.estimatedRowHeight = 50.0
但是,它不断突破约束,并出现如下错误:
"<NSLayoutConstraint:0x28211ce10 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x10859a4f0.height == 4.33333 (active)>"
还有更多的限制,但是这个限制说我的单元格内容视图只有4.3高度,但是我希望它随着标签的增长而增长。
我还尝试设置contentHuggingPriorities和底部锚点的优先级。我还将其与在线看到的代码或在线看到的IB约束进行了比较,它们都设置了4个约束:顶部,左侧,底部,右侧。 我也尝试过前后移动而不是左右移动-同样的结果。
任何帮助表示赞赏
这是我完整的AlbumTableViewCell:
class AlbumTableViewCell: UITableViewCell {
public private(set) var artworkImageView: UIImageView
public private(set) var titleLabel: UILabel
public private(set) var albumInfoLabel: UILabel
public private(set) var artistNameLabel: UILabel
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
self.artworkImageView = UIImageView(frame: .zero)
self.titleLabel = UILabel(frame: .zero)
self.albumInfoLabel = UILabel(frame: .zero)
self.artistNameLabel = UILabel(frame: .zero)
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.tintColor = UIColor.white
self.backgroundColor = UIColor.clear
self.contentView.backgroundColor = UIColor.barTintColor
self.contentView.layer.masksToBounds = false
self.contentView.layer.cornerRadius = 10.0
self.artworkImageView.layer.cornerRadius = 10.0
self.artworkImageView.layer.masksToBounds = true
self.artworkImageView.contentMode = .scaleAspectFit
self.artworkImageView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.artworkImageView)
// image view
self.artworkImageView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 5).isActive = true
self.artworkImageView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 5).isActive = true
self.artworkImageView.widthAnchor.constraint(equalToConstant: 80).isActive = true
self.artworkImageView.heightAnchor.constraint(equalToConstant: 80).isActive = true
self.titleLabel = UILabel(frame: .zero)
self.titleLabel.numberOfLines = 2
self.titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
self.titleLabel.textColor = UIColor.white
self.titleLabel.adjustsFontSizeToFitWidth = false
self.titleLabel.textAlignment = .left
self.titleLabel.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.titleLabel)
// title
self.titleLabel.leadingAnchor.constraint(equalTo: self.artworkImageView.trailingAnchor, constant: 5.0).isActive = true
self.titleLabel.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 5.0).isActive = true
self.titleLabel.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -5.0).isActive = true
self.titleLabel.heightAnchor.constraint(equalToConstant: 35).isActive = true
self.albumInfoLabel.numberOfLines = 1
self.albumInfoLabel.font = UIFont.preferredFont(forTextStyle: .subheadline)
self.albumInfoLabel.textColor = UIColor.lightGray
self.albumInfoLabel.adjustsFontSizeToFitWidth = true
self.albumInfoLabel.textAlignment = .left
self.albumInfoLabel.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.albumInfoLabel)
// albumInfoLabel
self.albumInfoLabel.topAnchor.constraint(equalTo: self.titleLabel.bottomAnchor, constant: 5.0).isActive = true
self.albumInfoLabel.leadingAnchor.constraint(equalTo: self.titleLabel.leadingAnchor).isActive = true
self.albumInfoLabel.trailingAnchor.constraint(equalTo: self.titleLabel.trailingAnchor).isActive = true
self.albumInfoLabel.heightAnchor.constraint(equalToConstant: 35).isActive = true
self.artistNameLabel = UILabel(frame: .zero)
self.artistNameLabel.numberOfLines = 1
self.artistNameLabel.font = UIFont.preferredFont(forTextStyle: .subheadline)
self.artistNameLabel.textColor = UIColor.lightGray
self.artistNameLabel.adjustsFontSizeToFitWidth = true
self.artistNameLabel.textAlignment = .left
self.artistNameLabel.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(self.artistNameLabel)
// albumInfoLabel
self.artistNameLabel.topAnchor.constraint(equalTo: self.albumInfoLabel.bottomAnchor, constant: 5.0).isActive = true
self.artistNameLabel.leadingAnchor.constraint(equalTo: self.albumInfoLabel.leadingAnchor).isActive = true
self.artistNameLabel.trailingAnchor.constraint(equalTo: self.albumInfoLabel.trailingAnchor).isActive = true
self.artistNameLabel.heightAnchor.constraint(equalToConstant: 35).isActive = true
let selectedView: UIView = UIView(frame: .zero)
selectedView.backgroundColor = UIColor.gray
selectedView.layer.cornerRadius = 10.0
selectedView.layer.masksToBounds = false
self.selectedBackgroundView = selectedView
}
override func layoutSubviews() {
super.layoutSubviews()
let contentViewFrame = self.contentView.frame
let insetContentViewFrame = contentViewFrame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
self.contentView.frame = insetContentViewFrame
self.selectedBackgroundView?.frame = insetContentViewFrame
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
此代码不再打破任何约束,但单元格也不会自动计算高度。这是我的表格视图控制器:
self.tableView.register(AlbumTableViewCell.self, forCellReuseIdentifier: "AlbumCell")
self.tableView.separatorStyle = .none
self.tableView.tableFooterView = UIView(frame: .zero)
self.tableView.rowHeight = UITableView.automaticDimension
self.tableView.estimatedRowHeight = 50.0
答案 0 :(得分:0)
var titleLabel = UILabel()
contentView.addSubview(titleLabel)
titleLabel.textColor = UIColor(red:0.32, green:0.17, blue:0.12, alpha:1.0)
titleLabel.font = UIFont.boldSystemFont(ofSize: 16.0)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
titleLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor, constant: 8).isActive = true
titleLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor, constant: 8).isActive = true
尝试一下。
答案 1 :(得分:0)
说实话,我不知道您到底出了什么问题,但是我可以肯定地说,您在单元格约束方面表现不佳,并且您想要一个动态单元格。
因此,假设您有一个具有4个视图的单元格artWrokImageView
,artNameLabel
,artDescriptionLabel
和artistNameLabel
首先,您需要确保这些视图在表格单元格的顶部和底部受到最大约束,因此,当您调用self.tableView.rowHeight = UITableView.automaticDimension
时,它知道如何动态扩展。
第二,您需要告诉表格何时出现视图
这是上面4个视图的演示。
Table View Controller:
class YourTableViewController : UITableViewController {
let customTableCellID = "customTableCellID";
override func viewDidLoad() {
super.viewDidLoad();
setupTable();
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tableView.estimatedRowHeight = 50;
self.tableView.rowHeight = UITableView.automaticDimension;
}
fileprivate func setupTable() {
tableView.register(YourCustomTableCell.self, forCellReuseIdentifier: customTableCellID);
}
}
extension YourTableViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return 1;
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1;
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: customTableCellID, for: indexPath) as! YourCustomTableCell
cell.artistNameLabel.text = "the real art";
cell.artworkImageView.image = UIImage(named: "mazen");
cell.artDescriptionLabel.text = "long long long long long long long long long long long long long long long long long long long long long long long long long description";
cell.artNameLabel.text = "someting"
return cell
}
}
单元格:
class YourCustomTableCell : UITableViewCell {
var artworkImageView : UIImageView = {
let imageView = UIImageView();
imageView.translatesAutoresizingMaskIntoConstraints = false;
return imageView;
}()
var artNameLabel : UILabel = {
let label = UILabel();
label.font = UIFont.boldSystemFont(ofSize: 20);
label.translatesAutoresizingMaskIntoConstraints = false;
return label
}()
var artDescriptionLabel : UILabel = {
let label = UILabel();
label.textColor = .darkGray;
label.numberOfLines = 0;
label.translatesAutoresizingMaskIntoConstraints = false;
return label;
}()
var artistNameLabel : UILabel = {
let label = UILabel();
label.textColor = .blue;
label.translatesAutoresizingMaskIntoConstraints = false;
return label;
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier);
setupCell();
}
fileprivate func setupCell() {
// add views
contentView.addSubview(artworkImageView);
contentView.addSubview(artNameLabel);
contentView.addSubview(artDescriptionLabel);
contentView.addSubview(artistNameLabel);
// layout views
// image view
artworkImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5).isActive = true;
artworkImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5).isActive = true;
artworkImageView.widthAnchor.constraint(equalToConstant: 80).isActive = true;
artworkImageView.heightAnchor.constraint(equalToConstant: 80).isActive = true;
// art name
artNameLabel.leadingAnchor.constraint(equalTo: artworkImageView.trailingAnchor, constant: 5).isActive = true;
artNameLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5).isActive = true;
artNameLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true;
artNameLabel.heightAnchor.constraint(equalToConstant: 35).isActive = true;
// descripion
artDescriptionLabel.leadingAnchor.constraint(equalTo: artworkImageView.trailingAnchor, constant: 5).isActive = true;
artDescriptionLabel.topAnchor.constraint(equalTo: artNameLabel.bottomAnchor, constant: 5).isActive = true;
artDescriptionLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true;
// in art description label don't set the height anchors so it can expand
// artist name
artistNameLabel.leadingAnchor.constraint(equalTo: artworkImageView.trailingAnchor, constant: 5).isActive = true;
artistNameLabel.topAnchor.constraint(equalTo: artDescriptionLabel.bottomAnchor, constant: 5).isActive = true;
artistNameLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true;
artistNameLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true; // this constraint is requierd for dynamic cell
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
如果您的回答不正确,请告诉我。
答案 2 :(得分:0)
您的tableviewcells 不不知道它们的高度应该是多少。没关系
您只需要给出足够的约束,以便它可以解决问题。你不是那样做!
我目前看到的主要问题是artworkImageView
不受限于top
和 bottom
。每个垂直的视图公理都必须从上到下进行约束。
您的第一个垂直公理就是图像。它没有底部约束。加上。因此tableviewcell知道需要多少调整自身大小。我强烈建议您查看this moment of WWDC。
同样在this moment的同一视频中,强烈建议您只是将视图转储到多个stackview中,并以此方式进行组织。所以这也是另一种选择。
PS:
请勿转储self
。它只是增加了线宽而没有其他好处。
将所有与标签/图像无关的与布局相关的设置移动到它们自己的实例中。例如
lazy label : UILabel = {
let label = UILabel()
label.text = "John"
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
frame : .zero
。仅UILabel()
表示帧为零。