我必须在UICollectionView
内添加一个UITableViewCell
。
collectionView
可以具有不同数量的项目。
因此,collectionView
应该在tableView
内部进行适当的调整。
我已经在我的项目中实现了这一点: https://github.com/vishalwaka/DynamicCollectionViewInsideTableViewCell
在我的情况下,设置collectionView
的高度后未调整单元格的高度。
如何设置collectionView
不可滚动,并同时显示tableviewcell
内部的所有内容。
答案 0 :(得分:2)
在collectionView
内创建一个UITableViewCell
,其前导,尾随,顶部,底部,高度约束如下:
现在,在您的tableViewCell
类中创建一个NSKeyValueObserver
,并将其添加到UICollectionView
的 contentSize 属性中,并将contentSize更改分配给collectionView的高度约束。 / p>
class FormCollectionTableViewCell: UITableViewCell{
var collectionViewObserver: NSKeyValueObservation?
override func awakeFromNib() {
super.awakeFromNib()
addObserver()
}
override func layoutSubviews() {
super.layoutSubviews()
layoutIfNeeded()
}
func addObserver() {
collectionViewObserver = collectionView.observe(\.contentSize, changeHandler: { [weak self] (collectionView, change) in
self?.collectionView.invalidateIntrinsicContentSize()
self?.collectionViewHrightConstarint.constant = collectionView.contentSize.height
self?.layoutIfNeeded()
})
}
deinit {
collectionViewObserver = nil
}
}
在您的viewController类中,使用以下代码:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.reloadData()
}
现在,您的表格视图将具有动态高度的集合视图。不要忘记禁用UICollectionView
的滚动和调整其流量。
答案 1 :(得分:0)
创建collectionView的以下子类:
class IntrinsicSizeCollectionView: UICollectionView {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
self.setup()
}
override func layoutSubviews() {
super.layoutSubviews()
if !self.bounds.size.equalTo(self.intrinsicContentSize) {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
get {
let intrinsicContentSize = self.contentSize
return intrinsicContentSize
}
}
func setup() {
self.isScrollEnabled = false
self.bounces = false
}
将collectionView添加到tableViewCell并设置其约束,将其前后,顶部,底部限制为单元格的边界。还要按照屏幕截图所示设置固有尺寸。
tableViewCell的大小应设置为UITableViewAutomaticdimension,并且还应在TableView的dataSource中设置此单元格的估算高度。
那应该是全部。
答案 2 :(得分:0)
检查完项目后,我建议您使用稍微不同的方法。
更新模型后,您可以询问集合视图布局新的内容大小将是多少(collectionViewLayout.collectionViewContentSize)。然后,您更新高度约束常数。
因此,您应该:
psql: FATAL: password authentication failed for user "foo"
的布局您的项目中的此修改应实现以下目的:
contentSize
请注意有关不需要任何其他布局更新调用的评论。只打电话
// Remove the content size observing logic.
func configureForVehicle(_ vehicle: Vehicle, selectedHouseType: String) {
self.vehicle = vehicle
applianceCollectionView.reloadData()
// Set the height constraint to the new value, found in the layout's content size info.
// Since the model (self.vehicle) was already updated, the layout will return the new content size.
// Because this is all happening while the cell is being reloaded, the cell will also resize properly.
// You don't need to perform any other setNeedsLayout/layoutIfNeeded calls.
self.applianceCollectionViewHeightConstraint.constant = applianceCollectionView.collectionViewLayout.collectionViewContentSize.height
}
应该足够了。不必要的布局更新可能会导致性能下降。
请注意,如果您希望动画高度变化而不重新加载单元格,则可以使用另一种方法。在这种情况下,您需要保留/查找要更新的单元格的引用,然后执行以下操作:
tableView.reloadRows(at: [indexPath], with: .automatic)
中。这将导致tableView重新布局其单元并设置高度变化的动画。来自beginUpdates() documentation:
您还可以在不重新加载单元格的情况下,使用此方法以及endUpdates()方法为行高设置动画效果。这组方法必须以调用endUpdates()作为结束。