如何动态约束单元格 contentView 的内部子视图?
How to dynamically constraint cell contentView's inside subViews?
在collectionCell的conentView中,我想根据不同的值来约束不同高度的垂直子视图,但问题是当内容滚动出屏幕时,高度意外改变,然后滚动回屏幕:
初始和正确的视图高度:
滚出屏幕,然后返回(视图高度因未知原因而改变):
下面是布局代码:
let contentView = cell.contentView
let row = indexPath.row
//calculate view height: relativeHeight value
let cellHeight = cell.frame.height
var relativeHeight = 0.6 * cellHeight
let values = [112.0, 116.0, 86.0, 95.0, 67.0, 76.0, 34.0, 43.0, 24.0, 35.0, 47.0, 66.0, 66.0, 57.0, 36.0, 64.0, 23.0, 22.0, 23.0, 22.0, 22.0, 22.0, 20.0, 23.0]
let Δvalue = values.max()! - values.min()!
let value = values[row]
if Δvalue != 0 {
let different = value - values.min()!
let ratio = CGFloat(different / Δvalue)
relativeHeight = ratio * relativeHeight
}
if contentView.subviews.count == 0 {
//time label
let timeLabel = UILabel()
timeLabel.tag = 3
timeLabel.textColor = self.textColor
timeLabel.font = UIFont.boldSystemFont(ofSize: 13)
contentView.addSubview(timeLabel)
timeLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
timeLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4),
timeLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
])
//vertical view
let valueView = UIView()
valueView.tag = 1
valueView.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.382) //1-0.618
contentView.addSubview(valueView)
valueView.translatesAutoresizingMaskIntoConstraints = false
//valueView.constraints.forEach{ [=10=].isActive = false }
NSLayoutConstraint.activate([
valueView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
valueView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
valueView.bottomAnchor.constraint(equalTo: timeLabel.topAnchor, constant: -4),
valueView.heightAnchor.constraint(equalToConstant: relativeHeight)
])
//value label
let valueLabel = UILabel()
valueLabel.tag = 2
valueLabel.textColor = self.textColor
valueLabel.font = UIFont.systemFont(ofSize: 12)
contentView.addSubview(valueLabel)
valueLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
valueLabel.bottomAnchor.constraint(equalTo: valueView.topAnchor, constant: -4),
valueLabel.centerXAnchor.constraint(equalTo: valueView.centerXAnchor)
])
}
如何解决此类布局限制问题?
非常感谢!
我想这个问题是因为没有参考 valueView
或您在分配后尝试设置的 heightConstraint
,检查 contentView.subviews.count == 0
。您为 UICollectionViewCell
准备视图层次结构的方式可能根本不是一个好的做法。在出列可重用视图时,必须涵盖每个条件以设置动态值。如果 contentView.subviews.count == 0
失败,这里没有任何处理程序。
修复是使用子类 UICollectionViewCell
来抽象 CollectionViewCell: UICollectionViewCell
中所有与视图相关的任务。我添加了一个属性 valueViewHeightConst
,初始约束值为0.0。我在计算要设置的高度值后设置准确值。
还引入了一种缓存机制,您无需在每次单元格出列时都计算 relativeHeight
。
请在 https://github.com/sauvikapple/WhosebugAnsToQ63743769 查看最终项目。
这是结果
在collectionCell的conentView中,我想根据不同的值来约束不同高度的垂直子视图,但问题是当内容滚动出屏幕时,高度意外改变,然后滚动回屏幕:
初始和正确的视图高度:
滚出屏幕,然后返回(视图高度因未知原因而改变):
下面是布局代码:
let contentView = cell.contentView
let row = indexPath.row
//calculate view height: relativeHeight value
let cellHeight = cell.frame.height
var relativeHeight = 0.6 * cellHeight
let values = [112.0, 116.0, 86.0, 95.0, 67.0, 76.0, 34.0, 43.0, 24.0, 35.0, 47.0, 66.0, 66.0, 57.0, 36.0, 64.0, 23.0, 22.0, 23.0, 22.0, 22.0, 22.0, 20.0, 23.0]
let Δvalue = values.max()! - values.min()!
let value = values[row]
if Δvalue != 0 {
let different = value - values.min()!
let ratio = CGFloat(different / Δvalue)
relativeHeight = ratio * relativeHeight
}
if contentView.subviews.count == 0 {
//time label
let timeLabel = UILabel()
timeLabel.tag = 3
timeLabel.textColor = self.textColor
timeLabel.font = UIFont.boldSystemFont(ofSize: 13)
contentView.addSubview(timeLabel)
timeLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
timeLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -4),
timeLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor)
])
//vertical view
let valueView = UIView()
valueView.tag = 1
valueView.backgroundColor = UIColor.systemBlue.withAlphaComponent(0.382) //1-0.618
contentView.addSubview(valueView)
valueView.translatesAutoresizingMaskIntoConstraints = false
//valueView.constraints.forEach{ [=10=].isActive = false }
NSLayoutConstraint.activate([
valueView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
valueView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
valueView.bottomAnchor.constraint(equalTo: timeLabel.topAnchor, constant: -4),
valueView.heightAnchor.constraint(equalToConstant: relativeHeight)
])
//value label
let valueLabel = UILabel()
valueLabel.tag = 2
valueLabel.textColor = self.textColor
valueLabel.font = UIFont.systemFont(ofSize: 12)
contentView.addSubview(valueLabel)
valueLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
valueLabel.bottomAnchor.constraint(equalTo: valueView.topAnchor, constant: -4),
valueLabel.centerXAnchor.constraint(equalTo: valueView.centerXAnchor)
])
}
如何解决此类布局限制问题?
非常感谢!
我想这个问题是因为没有参考 valueView
或您在分配后尝试设置的 heightConstraint
,检查 contentView.subviews.count == 0
。您为 UICollectionViewCell
准备视图层次结构的方式可能根本不是一个好的做法。在出列可重用视图时,必须涵盖每个条件以设置动态值。如果 contentView.subviews.count == 0
失败,这里没有任何处理程序。
修复是使用子类 UICollectionViewCell
来抽象 CollectionViewCell: UICollectionViewCell
中所有与视图相关的任务。我添加了一个属性 valueViewHeightConst
,初始约束值为0.0。我在计算要设置的高度值后设置准确值。
还引入了一种缓存机制,您无需在每次单元格出列时都计算 relativeHeight
。
请在 https://github.com/sauvikapple/WhosebugAnsToQ63743769 查看最终项目。