我希望UICollectionView(红色的)缩小到内容大小的高度,在这种情况下UICollectionViewCells(黄色的)因为有很多空的空间。我尝试的是使用:
override func layoutSubviews() {
super.layoutSubviews()
if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return self.collection.contentSize
}
但return self.collection.contentSize
总是返回(宽度,0)
由于这个原因,它缩小到高度值30(我在xib文件中为高度设置的值,虽然我有constaint> = 30)。
答案 0 :(得分:97)
我建议如下:
- 向集合视图添加高度约束。
- 将其优先级设置为999。
- 将其常量设置为可在故事板上合理显示的任何值。
- 将集合视图的底部相等约束更改为大于或等于。
- 将高度限制连接到插座。
- 每次在集合视图上重新加载数据时,请执行以下操作:
醇>
代码示例:
CGFloat height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
heightConstraint.constant = height
self.view.setNeedsLayout() Or self.view.layoutIfNeeded()
说明:额外的,如果您理解,您不必阅读。显然!! 强>
UI将尝试反映所有约束,无论它们的优先级如何。由于高度约束的优先级较低(999),因此底部约束类型大于或等于。每当高度约束常量设置为小于父视图高度的值时,集合视图将等于给定高度,从而实现两个约束。
但是,当高度约束常数设置为大于父视图高度的值时,两个约束都无法实现。因此,只有具有更高优先级的约束才能实现,即更大或相等的底部约束。
以下只是对经验的猜测。因此,它实现了一个常量。但是,它还尝试在结果用户界面中将错误用于其他未实现的较低优先级约束尽可能最低。因此,集合视图高度将等于父视图大小。
答案 1 :(得分:9)
我最后通过继承UICollectionView
并覆盖了一些方法,如下所示。
self.collectionViewLayout.collectionViewContentSize
返回intrinsicContentSize
,确保始终拥有正确的尺寸reloadData
)代码:
override func reloadData() {
super.reloadData()
self.invalidateIntrinsicContentSize()
}
override var intrinsicContentSize: CGSize {
return self.collectionViewLayout.collectionViewContentSize
}
但请注意,如果您显示大量数据,则会丢失“重复使用单元格”,尽管它们不适合屏幕。
答案 2 :(得分:5)
您必须将高度限制设置为等于内容大小
HeightConstraint.constant = collection.contentSize.height
答案 3 :(得分:5)
1)设置CollectionView的Fix Height。
2)创建此CollectionView高度常数的出口。 像:
IBOutlet NSLayoutConstraint * constHeight;
3)在您的.m文件中添加以下方法:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat height = collectionMenu.collectionViewLayout.collectionViewContentSize.height;
constHeight.constant = height;
}
答案 4 :(得分:2)
请遵循。
UICollectionView
calendarBaseViewHeight
是UICollectionView
身高变量重新加载集合视图后调用该函数
func resizeCollectionViewSize(){
calendarBaseViewHeight.constant = collectionView.contentSize.height
}
答案 5 :(得分:2)
使用d4Rk解决方案非常好,除了在我的情况下,它将继续切断我的收藏视图的底部(太短)。我发现这是因为内在内容大小有时为0,这会影响计算。 IDK。我所知道的就是解决了这个问题。
import UIKit
class SelfSizedCollectionView: UICollectionView {
override func reloadData() {
super.reloadData()
self.invalidateIntrinsicContentSize()
}
override var intrinsicContentSize: CGSize {
let s = self.collectionViewLayout.collectionViewContentSize
return CGSize(width: max(s.width, 1), height: max(s.height,1))
}
}
答案 6 :(得分:2)
-
class ContentSizedCollectionView: UICollectionView {
override var contentSize:CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
layoutIfNeeded()
return CGSize(width: UIView.noIntrinsicMetric, height: collectionViewLayout.collectionViewContentSize.height)
}
}
答案 7 :(得分:1)
首先计算细胞数,然后将其与细胞高度相乘,然后在此方法中返回高度
collectionView.frame = CGRectMake (x,y,w,collectionView.collectionViewLayout.collectionViewContentSize.height); //objective c
//[collectionView reloadData];
collectionView.frame = CGRect(x: 0, y: 0, width: width, height: collectionView.collectionViewLayout.collectionViewContentSize.height) // swift
答案 8 :(得分:0)
在您的UICollectionView
上设置约束,例如Trailing
,Leading
和Bottom
:
如果您更详细地查看我的身高限制,因为它纯粹是为演示图板而设计,所以我没有收到错误,我将其保留为Remove at build time
。实际的高度限制在下面的代码中设置。
我的DrawerCollectionView
代码,该代码已设置为集合视图Custom Class
:
import UIKit
class DrawerCollectionView: UICollectionView {
override func didMoveToSuperview() {
super.didMoveToSuperview()
heightAnchor.constraint(equalToConstant: contentSize.height).isActive = true
}
}
答案 9 :(得分:0)
在Swift 5和Xcode 10.2.1中
1)修复CollectionView的高度
2)创建您的CollectionView的出口
IBOutlet weak var myCollectionViewHeight: NSLayoutConstraint!
3)使用以下代码
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
myCollectionViewHeight.constant = height
self.view.layoutIfNeeded()
}
答案 10 :(得分:0)
为我工作
let heightRes = resCollectionView.collectionViewLayout.collectionViewContentSize.height
foodHeightConstrant.constant = height.advanced(by: 1 )
foodCollectionView.setNeedsLayout()
foodCollectionView.layoutIfNeeded()
答案 11 :(得分:0)
获取单元格的高度。像这样
let cellHeight = cell.frame.height
获取集合视图的来源
let cvOrigin = collectionView.frame.origin
获取集合视图的宽度
let cvWidth = collectionView.bounds.width
设置内容视图的框架
collection.frame = CGRect(x: cvOrigin.x, y: cvOrigin.y, width: cvWidth, height: cellHeight )
答案 12 :(得分:0)
对于我来说,这似乎是最简单的解决方案。
class SelfSizingCollectionView: UICollectionView {
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
isScrollEnabled = false
}
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override func reloadData() {
super.reloadData()
self.invalidateIntrinsicContentSize()
}
override var intrinsicContentSize: CGSize {
return contentSize
}
}
您可能不需要覆盖reloadData
答案 13 :(得分:0)
如果设置了集合视图的高度约束。只需观察viewDidLoad中contentSize
的变化并更新约束即可。
self.contentSizeObservation = collectionView.observe(\.contentSize, options: [.initial, .new]) { [weak self] collectionView, change in
guard let `self` = self else { return }
guard self.collectionView.contentSize != .zero else { return }
self.collectionViewHeightLayoutConstraint.constant = self.collectionView.contentSize.height
}
答案 14 :(得分:0)
我有一个多行、多选的 UICollectionView
子类,其中单元格具有固定高度且左对齐从左到右流动。它嵌入在垂直滚动视图内的垂直堆栈视图中。请参阅标签“属性类型”下方的 UI 组件。
为了使集合视图适合其 contentSize
的高度,我必须这样做(请注意,这一切都在 UICollectionView
子类中):
给集合视图一个优先级为 999
的非零最小高度约束。将集合视图自动调整到其内容高度在零高度下根本不起作用。
let minimumHeight = heightAnchor.constraint(greaterThanOrEqualToConstant: 1)
minimumHeight.priority = UILayoutPriority(999)
minimumHeight.isActive = true
将集合视图的内容拥抱优先级设置为纵轴的 .required
。
setContentHuggingPriority(.required, for: .vertical)
调用 reloadData()
之后是以下调用:
invalidateIntrinsicContentSize()
setNeedsLayout()
layoutIfNeeded()
例如,我的子类中有一个 setItems()
函数:
func setItems(_ items: [Item]) {
self.items = items
selectedIndices = []
reloadData()
invalidateIntrinsicContentSize()
setNeedsLayout()
layoutIfNeeded()
}
按如下方式覆盖 contentSize
和 intrinsicContentSize
:
override var intrinsicContentSize: CGSize {
return contentSize
}
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
setNeedsLayout()
layoutIfNeeded()
}
}
答案 15 :(得分:0)
将 UICollectionView 的高度调整到其内容大小的高度 ??
SWIFT 5
final class MyViewController: UIViewController {
// it's important to declare layout as separate constant due to late update in viewDidLayoutSubviews()
private let layout = UICollectionViewFlowLayout()
private lazy var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView()
setupCollectionViewConstraints()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
updateFlowLayout()
}
private func setupCollectionView() {
view.addSubview(collectionView)
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "UICollectionViewCell")
collectionView.dataSource = self
}
private func setupCollectionViewConstraints() {
// your collectionView constraints setup
}
private func updateFlowLayout() {
let height = collectionView.collectionViewLayout.collectionViewContentSize.height
layout.itemSize = CGSize(width: view.frame.width, height: height)
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = .zero
layout.minimumLineSpacing = .zero
layout.sectionInset = UIEdgeInsets.zero
}
}
extension MyViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {...}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {...}
}