为什么 UITableViewCell 缩小了 contentView?
Why UITableViewCell shrinks contentView?
这是我要制作的UITableView
:
为了实现这一点,我将单元格contentView
分成三部分。
1 - fromView:包含开始时间和 class 类型。高度将为 contentView
的 30%
2 - infoView:包含时钟图像、class 姓名和教授姓名。高度将为 contentView
的 40%。
3 - toView:包含结束时间和位置。高度将是 space 剩下的 (30%)。
首先,在详细介绍之前,我决定只展示这个容器。为了理解一个问题,我画了它们(分别为绿色、红色、蓝色)。
将它们添加到 contentView
后,这里是我对这些容器的约束:
fromView.easy.layout(Top(), Left(), Right(), Height(*0.3).like(contentView))
infoView.easy.layout(Top().to(fromView), Left(), Right(), Height(*0.4).like(contentView))
toView.easy.layout(Top().to(infoView), Left(), Right(), Bottom())
看来一切正常。启动后,我以为我会看到它们,但事情是这样的:
我认为单元格不知道它需要多大,所以我决定实现以下功能:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
在此之后,UITableView
比以前更正确地显示了容器。但是,我计划将一些 UILabel
和其他 views
添加到该容器中(看第一张图片)。换句话说,我不知道单元格需要多大。它需要是动态的。无论如何,我尝试将这些标签添加到容器中,也许在那之后,一个单元格会计算出高度。这是我的做法:
func setupViews() {
fromView.addSubviews(fromTime, classType)
toView.addSubviews(toTime, room)
infoView.addSubviews(clockImage, teacherName, subjectName)
contentView.addSubviews(toView, fromView, infoView)
}
func setupConstraints() {
fromView.easy.layout(Top(), Left(), Right(), Height(*0.3).like(contentView))
infoView.easy.layout(Top().to(fromView), Left(), Right(), Height(*0.4).like(contentView))
toView.easy.layout(Top().to(infoView), Left(), Right(), Bottom())
fromTime.easy.layout(CenterY(), Left(8))
fromTime.setContentHuggingPriority(.required, for: .horizontal)
fromTime.setContentCompressionResistancePriority(.required, for: .horizontal)
classType.easy.layout(CenterY(), Left(8).to(fromTime))
clockImage.easy.layout(CenterY(), Left(16), Width(24), Height(24))
subjectName.easy.layout(CenterY(-8), Left().to(classType, .left), Right())
teacherName.easy.layout(Top(8).to(subjectName), Left().to(subjectName, .left), Right())
toTime.easy.layout(CenterY(), Left(8))
toTime.setContentHuggingPriority(.required, for: .horizontal)
toTime.setContentCompressionResistancePriority(.required, for: .horizontal)
room.easy.layout(CenterY(), Left(8).to(toTime))
}
但无论如何,问题又出现了:
我想,问题是我根据contentView
的高度给容器高度,但是contentView
不知道它的高度。但我也不知道它需要多高,因为它需要根据标签的大小而定。那么,如何解决这个问题呢?
尝试为单元格内的主视图设置高度限制。
不要为容器设置高度。您必须确保单元格的顶部和底部通过约束连接。我的建议是去掉容器,直接将所有标签和图像添加到单元格中,然后像这样创建约束。
然后设置tableView.rowHeight = UITableView.automaticDimension
,或从tableView(_:heightForRowAt:)
returnUITableView.automaticDimension
看起来你想要的是根据内容的自动布局计算的动态高度。将代表更新为 return,heightForRowAt
的 UITableViewAutomaticDimension
和一些好的估计,例如 estimatedHeightForRowAt
的 150:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
然后您可以使用自动布局设置内容的大小,table 会为您动态计算单元格的高度。
估计高度用于滚动目的 - 一个好的估计将为您提供良好的滚动体验(动态高度仅在单元格显示时计算,因此对于尚未显示的单元格,tableView
将使用滚动时的估计)。
这是我要制作的UITableView
:
为了实现这一点,我将单元格contentView
分成三部分。
1 - fromView:包含开始时间和 class 类型。高度将为 contentView
的 30%2 - infoView:包含时钟图像、class 姓名和教授姓名。高度将为 contentView
的 40%。
3 - toView:包含结束时间和位置。高度将是 space 剩下的 (30%)。
首先,在详细介绍之前,我决定只展示这个容器。为了理解一个问题,我画了它们(分别为绿色、红色、蓝色)。
将它们添加到 contentView
后,这里是我对这些容器的约束:
fromView.easy.layout(Top(), Left(), Right(), Height(*0.3).like(contentView))
infoView.easy.layout(Top().to(fromView), Left(), Right(), Height(*0.4).like(contentView))
toView.easy.layout(Top().to(infoView), Left(), Right(), Bottom())
看来一切正常。启动后,我以为我会看到它们,但事情是这样的:
我认为单元格不知道它需要多大,所以我决定实现以下功能:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
在此之后,UITableView
比以前更正确地显示了容器。但是,我计划将一些 UILabel
和其他 views
添加到该容器中(看第一张图片)。换句话说,我不知道单元格需要多大。它需要是动态的。无论如何,我尝试将这些标签添加到容器中,也许在那之后,一个单元格会计算出高度。这是我的做法:
func setupViews() {
fromView.addSubviews(fromTime, classType)
toView.addSubviews(toTime, room)
infoView.addSubviews(clockImage, teacherName, subjectName)
contentView.addSubviews(toView, fromView, infoView)
}
func setupConstraints() {
fromView.easy.layout(Top(), Left(), Right(), Height(*0.3).like(contentView))
infoView.easy.layout(Top().to(fromView), Left(), Right(), Height(*0.4).like(contentView))
toView.easy.layout(Top().to(infoView), Left(), Right(), Bottom())
fromTime.easy.layout(CenterY(), Left(8))
fromTime.setContentHuggingPriority(.required, for: .horizontal)
fromTime.setContentCompressionResistancePriority(.required, for: .horizontal)
classType.easy.layout(CenterY(), Left(8).to(fromTime))
clockImage.easy.layout(CenterY(), Left(16), Width(24), Height(24))
subjectName.easy.layout(CenterY(-8), Left().to(classType, .left), Right())
teacherName.easy.layout(Top(8).to(subjectName), Left().to(subjectName, .left), Right())
toTime.easy.layout(CenterY(), Left(8))
toTime.setContentHuggingPriority(.required, for: .horizontal)
toTime.setContentCompressionResistancePriority(.required, for: .horizontal)
room.easy.layout(CenterY(), Left(8).to(toTime))
}
但无论如何,问题又出现了:
我想,问题是我根据contentView
的高度给容器高度,但是contentView
不知道它的高度。但我也不知道它需要多高,因为它需要根据标签的大小而定。那么,如何解决这个问题呢?
尝试为单元格内的主视图设置高度限制。
不要为容器设置高度。您必须确保单元格的顶部和底部通过约束连接。我的建议是去掉容器,直接将所有标签和图像添加到单元格中,然后像这样创建约束。
然后设置tableView.rowHeight = UITableView.automaticDimension
,或从tableView(_:heightForRowAt:)
UITableView.automaticDimension
看起来你想要的是根据内容的自动布局计算的动态高度。将代表更新为 return,heightForRowAt
的 UITableViewAutomaticDimension
和一些好的估计,例如 estimatedHeightForRowAt
的 150:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
然后您可以使用自动布局设置内容的大小,table 会为您动态计算单元格的高度。
估计高度用于滚动目的 - 一个好的估计将为您提供良好的滚动体验(动态高度仅在单元格显示时计算,因此对于尚未显示的单元格,tableView
将使用滚动时的估计)。