嵌套的 UICollectionView 与 UICollectionViewCompositionalLayout
Nested UICollectionView with UICollectionViewCompositionalLayout
我有两个 UICollectionView
,UICV1
其中一个单元格中嵌套了 UICV2
。我想要的是 UICV2
根据其内容自行调整大小,但 contentSize
和 collectionViewLayout.collectionViewContentSize
都是 zero
.
此设置在 之前完全相同,唯一的区别是 UICV2
是 UITableView
。由于代码重构和重用,我改用UICollectionView
。新的视图层次结构看起来像这样:
+--------------------+
| UICV1 |
| +----------------+ |
| | Cell | |
| | +------------+ | |
| | | Stack View | | |
| | | +--------+ | | |
| | | | UICV2 | | | |
| | | +--------+ | | |
| | +------------+ | |
| +----------------+ |
| ... |
+--------------------+
两个集合视图都配置了 UICollectionViewCompositionalLayout
:
// UICV1
let layout1 = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(100)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: itemSize,
subitem: item,
count: 1
)
return NSCollectionLayoutSection(group: group)
}
// UICV2
let layout2 = UICollectionViewCompositionalLayout.list(using: {
var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
configuration.headerMode = .none
configuration.headerTopPadding = 0
return configuration
}())
let collectionView = SelfSizingCollectionView(
frame: .zero,
collectionViewLayout: layout2
)
这是自定义大小集合视图的代码:
class SelfSizingCollectionView: UICollectionView {
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
isScrollEnabled = false
contentInsetAdjustmentBehavior = .never
}
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override func layoutSubviews() {
super.layoutSubviews()
invalidateIntrinsicContentSize()
}
override var intrinsicContentSize: CGSize {
layoutIfNeeded()
// This is always (0.0, 0.0)
return CGSize(
width: UIView.noIntrinsicMetric,
height: collectionViewLayout.collectionViewContentSize.height
)
}
}
我正在使用 NSDiffableDataSourceSnapshot
为两个集合视图提供数据,如果这有什么不同的话。
我希望有人能在这里帮助我,在 SelfSizingCollectionView
的不同点上玩 invalidateLayout()
、setNeedsLayout()
和 layoutIfNeeded()
的组合后我完全迷失了。
我找到了大量关于自调整集合视图的答案,我将其合并到我的代码中,但它们似乎不适用于全新的 UICollectionViewCompositionalLayout
。
我现在通过将初始边界传递给 SelfSizingCollectionView
来修复它。不知道这是否带有警告或任何不可预见的副作用,但目前有效。
let collectionView = SelfSizingCollectionView(
frame: bounds,
collectionViewLayout: layout2
)
我有两个 UICollectionView
,UICV1
其中一个单元格中嵌套了 UICV2
。我想要的是 UICV2
根据其内容自行调整大小,但 contentSize
和 collectionViewLayout.collectionViewContentSize
都是 zero
.
此设置在 之前完全相同,唯一的区别是 UICV2
是 UITableView
。由于代码重构和重用,我改用UICollectionView
。新的视图层次结构看起来像这样:
+--------------------+
| UICV1 |
| +----------------+ |
| | Cell | |
| | +------------+ | |
| | | Stack View | | |
| | | +--------+ | | |
| | | | UICV2 | | | |
| | | +--------+ | | |
| | +------------+ | |
| +----------------+ |
| ... |
+--------------------+
两个集合视图都配置了 UICollectionViewCompositionalLayout
:
// UICV1
let layout1 = UICollectionViewCompositionalLayout { sectionIndex, layoutEnvironment in
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(100)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: itemSize,
subitem: item,
count: 1
)
return NSCollectionLayoutSection(group: group)
}
// UICV2
let layout2 = UICollectionViewCompositionalLayout.list(using: {
var configuration = UICollectionLayoutListConfiguration(appearance: .insetGrouped)
configuration.headerMode = .none
configuration.headerTopPadding = 0
return configuration
}())
let collectionView = SelfSizingCollectionView(
frame: .zero,
collectionViewLayout: layout2
)
这是自定义大小集合视图的代码:
class SelfSizingCollectionView: UICollectionView {
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
isScrollEnabled = false
contentInsetAdjustmentBehavior = .never
}
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override func layoutSubviews() {
super.layoutSubviews()
invalidateIntrinsicContentSize()
}
override var intrinsicContentSize: CGSize {
layoutIfNeeded()
// This is always (0.0, 0.0)
return CGSize(
width: UIView.noIntrinsicMetric,
height: collectionViewLayout.collectionViewContentSize.height
)
}
}
我正在使用 NSDiffableDataSourceSnapshot
为两个集合视图提供数据,如果这有什么不同的话。
我希望有人能在这里帮助我,在 SelfSizingCollectionView
的不同点上玩 invalidateLayout()
、setNeedsLayout()
和 layoutIfNeeded()
的组合后我完全迷失了。
我找到了大量关于自调整集合视图的答案,我将其合并到我的代码中,但它们似乎不适用于全新的 UICollectionViewCompositionalLayout
。
我现在通过将初始边界传递给 SelfSizingCollectionView
来修复它。不知道这是否带有警告或任何不可预见的副作用,但目前有效。
let collectionView = SelfSizingCollectionView(
frame: bounds,
collectionViewLayout: layout2
)