ios - StackView 中的多个 CollectionView
问题描述
我目前有几个使用组合布局的集合视图,我试图将它们添加到两个独立的垂直堆栈视图中。我的一个集合视图将进入 headerContentView,另一个将进入实际的 contentView。
我的 collectionView 应该通过使内在内容大小无效来自行调整大小。但是,由于某种原因,只有一个 collectionView 是可见的,因为它会将自身调整为内容大小。但是,另一个的高度将为 0。请注意,包含第二个 collectionView 的堆栈视图的高度也为零。
我需要帮助才能正确调整集合视图的大小。 谢谢你的时间。
堆栈视图:
internal let contentStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
return stackView
}()
StackView 上的约束:
private func setUpView() {
backgroundColor = .blue
layoutMargins = UIEdgeInsets(top: 0, left: 16, bottom: 24, right: 16)
addSubview(headerView)
addSubview(contentStackView)
// Preserve superview layout margins so that sub-elements can be laid out using layoutMarginsGuide
contentStackView.preservesSuperviewLayoutMargins = true
[headerView, contentStackView].forEach { $0.translatesAutoresizingMaskIntoConstraints = false }
NSLayoutConstraint.activate([
headerView.topAnchor.constraint(equalTo: topAnchor),
contentStackView.topAnchor.constraint(equalTo: headerView.bottomAnchor, constant: 16),
layoutMarginsGuide.bottomAnchor.constraint(lessThanOrEqualTo: contentStackView.bottomAnchor),
headerView.leadingAnchor.constraint(equalTo: leadingAnchor),
headerView.trailingAnchor.constraint(equalTo: trailingAnchor),
contentStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
contentStackView.trailingAnchor.constraint(equalTo: trailingAnchor)
])
}
private func setUpHeaderView() {
// Preserve superview layout margins so that sub-elements can be laid out using layoutMarginsGuide
headerView.preservesSuperviewLayoutMargins = true
headerContentStackView.preservesSuperviewLayoutMargins = true
headerView.addSubview(headerContentStackView)
headerContentStackView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
headerContentStackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
headerView.bottomAnchor.constraint(lessThanOrEqualTo: headerContentStackView.bottomAnchor),
headerContentStackView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor),
headerContentStackView.trailingAnchor.constraint(equalTo: headerView.trailingAnchor)
])
// Add header contents to header content stack view
headerContentStackView.addArrangedSubview(headerBarView)
headerContentStackView.addArrangedSubview(notificationView)
}
组成布局:
private static func generateCompositionalLayout() -> UICollectionViewLayout {
// Items
let itemSize: NSCollectionLayoutSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(UIConstantsIconTileCollectionView.PhaseTwo.fractionalWidthForItems),
heightDimension: .fractionalHeight(UIConstantsIconTileCollectionView.PhaseTwo.fullWidthOrHeight)
)
let fullItem: NSCollectionLayoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
// Groups
let groupSize: NSCollectionLayoutSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(UIConstantsIconTileCollectionView.PhaseTwo.fullWidthOrHeight),
heightDimension: .fractionalWidth(UIConstantsIconTileCollectionView.PhaseTwo.fractionalWidthForGroups)
)
let group: NSCollectionLayoutGroup = NSCollectionLayoutGroup.horizontal(
layoutSize: groupSize,
subitem: fullItem,
count: UIConstantsIconTileCollectionView.PhaseTwo.numberOfItemsPerGroup
)
group.interItemSpacing = .fixed(UIConstantsIconTileCollectionView.PhaseTwo.interGroupSpacing)
// Section
let section: NSCollectionLayoutSection = NSCollectionLayoutSection(group: group)
section.contentInsets = NSDirectionalEdgeInsets(
top: 0,
leading: UIConstantsIconTileCollectionView.PhaseTwo.interSectionSpacing,
bottom: 0,
trailing: UIConstantsIconTileCollectionView.PhaseTwo.interSectionSpacing
)
return UICollectionViewCompositionalLayout(section: section)
}
自选尺寸系列视图:
// MARK: - View Layout
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return contentSize
}
解决方案
我的解决方案是我实现 CollectionViewController 的方式。我正在覆盖 loadView() 并用 collectionView 替换视图本身。示例,如下:
override func loadView() {
view = collectionView
}
但是,当我覆盖 viewDidLoad 并将 collectionView 添加为子视图并将其约束到视图控制器视图时,它工作得很好。示例,如下:
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
// Constraint collectionView -> view
}
我找不到为什么这与 stackViews 配合得更好,因为它让我大吃一惊,但这解决了这个问题。如果有人对为什么基本上只有一个 collectionView 的容器视图与 stackView 配合得很好有更多的知识,我将不胜感激。
推荐阅读
- dplyr - 使用 dplyr 的组滞后差异
- android - 由于 0dp 高度,ConstraintLayout 中的 Android EditText 是可滚动的
- python - `driver.execute_script("...")` 和 `driver.get("javascript: ..."` 与 geckodriver/Firefox 有什么区别?
- javascript - 如何按波斯字母对列表进行排序?
- javascript - 如何在没有性能问题的情况下访问网站的所有 URL
- css - 使用哪种嵌套结构 (BEM),无需修改 HTML
- typescript - Android 的 IONIC 部署问题
- selenium - 无法通过 Jenkins 作业触发某些应用程序的测试
- ios - CALayer 裁剪
- android - Android CustomDialog minWidth