英文:
Having trouble setting constraints of 2 views one on top and one on bottom in a custom UITableViewCell
问题
我目前正尝试在CustomCell中叠加两个视图。
我遇到的问题是只有顶部视图显示出来。
调试视图时,发现顶部视图的高度是模糊的,底部视图的高度和垂直位置也是模糊的。
我目前使用func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
方法设置这些自定义单元格的高度,将其设置为UITableView.automaticDimension
,并在CustomCell的layoutSubviews
方法中使用以下代码设置约束。
我漏掉了什么?
谢谢
tableView与CustomCells当前的外观如下,它应该在绿色视图下有一个黑色视图,之间有10个间距。
CustomTableViewCell
/// 将其添加到contentView。这在`init()`中调用
private func setupUI() {
setupCellContentView()
self.contentView.addSubview(topContainerView)
self.contentView.addSubview(bottomContainerView)
}
override func layoutSubviews() {
super.layoutSubviews()
let topContainerViewViewConstraints = [
topContainerView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10),
topContainerView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10),
topContainerView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -10),
]
let bottomContainerViewConstraints = [
bottomContainerView.topAnchor.constraint(equalTo: topContainerView.bottomAnchor, constant: 10),
bottomContainerView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10),
bottomContainerView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -10),
bottomContainerView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -10)
]
NSLayoutConstraint.activate(topContainerViewViewConstraints)
NSLayoutConstraint.activate(bottomContainerViewConstraints)
}
/// 底部容器视图的设置方式与topContainerView相同。
lazy var topContainerView: UIView = {
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
container.backgroundColor = .green
return container
}()
TableView
class MainViewController: UIViewController {
private func setupUI() {
self.edgesForExtendedLayout = []
self.view.backgroundColor = .none
self.view.addSubview(contentView)
}
private func setupConstraintsForContentView() {
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
contentView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
])
}
}
extension MainViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
viewModel.scoresData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell: ScoresTableViewCell = tableView.dequeueReusableCell(withIdentifier: "scoresTableViewCell",
for: indexPath) as? ScoresTableViewCell else {
return UITableViewCell()
}
cell.setupCellData(with: viewModel.scoresData[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
英文:
I'm currently trying to have 2 views on top of each other in a CustomCell.
The issue i'm running into is only the top view gets displayed.
Debugging the view it shows that the height for the top view is ambiguous and for the bottom view the height and vertical position is ambiguous.
I'm currently setting the height for these custom cells using the func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
method and setting it to UITableView.automaticDimension
and setting the cosntraints using the code below inside the CustomCells layoutSubviews
method.
What am I missing?
Thank you
What the tableView with the customCells currently looks like, it should have a greenView and a blackView under the greenView with a space of 10.
CustomTableViewCell
/// Adds it to contentView. This get's called in the `init()`
private func setupUI() {
setupCellContentView()
self.contentView.addSubview(topContainerView)
self.contentView.addSubview(bottomContainerView)
}
override func layoutSubviews() {
super.layoutSubviews()
let topContainerViewViewConstraints = [
topContainerView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10),
topContainerView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10),
topContainerView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -10),
]
let bottomContainerViewConstraints = [
bottomContainerView.topAnchor.constraint(equalTo: topContainerView.bottomAnchor, constant: 10),
bottomContainerView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 10),
bottomContainerView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -10),
bottomContainerView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -10)
]
NSLayoutConstraint.activate(topContainerViewViewConstraints)
NSLayoutConstraint.activate(bottomContainerViewConstraints)
}
/// Bottom container view is set up the exact same way as topContainerView.
lazy var topContainerView: UIView = {
let container = UIView()
container.translatesAutoresizingMaskIntoConstraints = false
container.backgroundColor = .green
return container
}()
TableView
class MainViewController: UIViewController {
private func setupUI() {
self.edgesForExtendedLayout = []
self.view.backgroundColor = .none
self.view.addSubview(contentView)
}
private func setupConstraintsForContentView() {
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
contentView.leadingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor),
])
}
}
extension MainViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
viewModel.scoresData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell: ScoresTableViewCell = tableView.dequeueReusableCell(withIdentifier: "scoresTableViewCell",
for: indexPath) as? ScoresTableViewCell else {
return UITableViewCell()
}
cell.setupCellData(with: viewModel.scoresData[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
答案1
得分: 1
你尚未为任何容器视图分配高度约束,这导致它们都没有高度信息。宽度是明确的,因为视图固定在内容视图的左右两侧,而内容视图的宽度由表视图本身决定;但内容视图的高度是运行时需要确定的未知因素,而你没有提供任何帮助。
当顶部容器视图被分配一个高度时,它的高度将不再模糊不清,因此底部也将变得明确,进而底部容器视图的顶部也将不再模糊不清。当底部容器视图被分配一个高度时,就不会再有进一步的模糊不清,内容视图(因此单元格)将采用正确的高度。
因此,你从调试器中获取的信息是正确的。我唯一感到惊讶的是,你居然可以看到任何单元格!
英文:
You have not assigned any constraints to either container view that would give either of them any height. The width is unambiguous because the views are pinned to the left and right of the content view, whose width is in turn determined by the table view itself; but the height of the content view is the unknown that the runtime is trying to determine, and you are not giving it any help.
When the top container view is given a height, its height will no longer be ambiguous and its bottom will therefore be known, and in turn the top of the bottom container view will no longer be ambiguous. When the bottom container view is given a height, there will be no further ambiguity and the content view (and hence the cell) will adopt a correct height.
So the information you have gathered from the debugger is correct. The only surprise as far as I'm concerned is that you can see any cell at all!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论