ios 如何将 UICollectionView 的高度调整为 UICollectionView 的内容大小的高度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42437966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:56:09  来源:igfitidea点击:

How to adjust height of UICollectionView to be the height of the content size of the UICollectionView?

iosswiftuicollectionviewnslayoutconstraintios-autolayout

提问by charbinary

I would like the UICollectionView (The red one) to shrink to the height of the content size in this case UICollectionViewCells(the yellow ones) because there is a lot of empty space. What I tried is to use:

我希望 UICollectionView(红色的)在这种情况下缩小到内容大小的高度 UICollectionViewCells(黄色的),因为有很多空白空间。我尝试使用的是:

override func layoutSubviews() {
    super.layoutSubviews()
    if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
        self.invalidateIntrinsicContentSize()
    }
}

override var intrinsicContentSize: CGSize {
    return self.collection.contentSize
}

but return self.collection.contentSizealways return (width, 0) and for this reason it shrinks too much to value of height 30 (The value which I set in the XIB file for the height, although I have constaint >= 30).

return self.collection.contentSize总是返回 (width, 0) 并且因此它收缩太多到高度 30 的值(我在 XIB 文件中为高度设置的值,尽管我有 constaint >= 30)。

enter image description here

在此处输入图片说明

回答by hasan

I would suggest the following:

我建议如下:

  1. Add a height constraint to your collection view.
  2. Set its priority to 999.
  3. Set its constant to any value that makes it reasonably visible on the storyboard.
  4. Change the bottom equal constraint of the collection view to greater or equal.
  5. Connect the height constraint to an outlet.
  6. Every time you reload the data on the collection view do the following:
  1. 向集合视图添加高度约束。
  2. 将其优先级设置为 999。
  3. 将其常量设置为使其在故事板上合理可见的任何值。
  4. 将集合视图的底部相等约束更改为更大或相等。
  5. 将高度约束连接到出口。
  6. 每次在集合视图上重新加载数据时,请执行以下操作:

Code Sample:

代码示例:

CGFloat height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
heightConstraint.constant = height
self.view.setNeedsLayout() Or self.view.layoutIfNeeded()

Explanation: Extra, You don't have to read if you understand it. obviously!!

说明: 额外,如果你理解它,你不必阅读。明显地!!

The UI will try to reflect all the constraints no matter what are their priorities. Since the height constraint has lower priority of (999), and a bottom constraint of type greater or equal. whenever, the height constraint constant is set to a value less than the parent view height the collection view will be equal to the given height, achieving both constraints.

UI 将尝试反映所有约束,无论它们的优先级是什么。由于高度约束具有较低的优先级(999)和类型大于或等于的底部约束。每当高度约束常量设置为小于父视图高度的值时,集合视图将等于给定的高度,实现两个约束。

But, when the height constraint constant set to a value more than the parent view height both constraints can't be achieved. Therefore, only the constraint with the higher priority will be achieved which is the greater or equal bottom constraint.

但是,当高度约束常量设置为大于父视图高度的值时,两个约束都无法实现。因此,只有具有较高优先级的约束才会被实现,即更大或相等的底部约束。

The following is just a guess from an experience. So, it achieves one constrant. But, it also tries to make the errorin the resulted UI for the other un-achieved lower priority constraint as lowest as possible. Therefore, the collection view height will be equal to the parent view size.

以下只是经验的猜测。因此,它实现了一个常数。但是,它还尝试使其他未实现的较低优先级约束的结果 UI 中的错误尽可能低。因此,集合视图高度将等于父视图大小。

回答by Parth Patel

1) Set Fix Height of your CollectionView.

1) 设置 CollectionView 的固定高度。

2) Create Outlet of this CollectionView Height Constant. Like :

2) 创建此 CollectionView 高度常量的出口。喜欢 :

IBOutlet NSLayoutConstraint *constHeight;

IBOutlet NSLayoutConstraint *constHeight;

3) Add below method in your .m file:

3) 在 .m 文件中添加以下方法:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    CGFloat height = collectionMenu.collectionViewLayout.collectionViewContentSize.height;
    constHeight.constant = height;
}

回答by d4Rk

I ended up, by subclassing the UICollectionViewand overriding some methods as follows.

我最终通过子类化UICollectionView并覆盖了一些方法,如下所示。

  • Returning self.collectionViewLayout.collectionViewContentSizefor intrinsicContentSizemakes sure, to always have the correct size
  • Then just call it whenever it might change (like on reloadData)
  • 返回self.collectionViewLayout.collectionViewContentSizeintrinsicContentSize确保始终具有正确的尺寸
  • 然后只要它可能改变就调用它(比如 on reloadData

Code:

代码:

override func reloadData() {
    super.reloadData()
    self.invalidateIntrinsicContentSize()
}

override var intrinsicContentSize: CGSize {
    return self.collectionViewLayout.collectionViewContentSize
}

But be aware, that you lose "cell re-using", if you display large sets of data, eventhough they don't fit on the screen.

但请注意,如果您显示大量数据,即使它们不适合屏幕,也会失去“单元重用”。

回答by Bhanupriya

You have to set height constraint as equal to content size

您必须将高度约束设置为等于内容大小

HeightConstraint.constant = collection.contentSize.height 

回答by iOS

In Swift 5 and Xcode 10.2.1

在 Swift 5 和 Xcode 10.2.1 中

1) Fix Height of the CollectionView

1) 修复 CollectionView 的高度

2) Create Outlet of your CollectionView

2) 创建 CollectionView 的出口

IBOutlet weak var myCollectionViewHeight: NSLayoutConstraint!

3) Use below code

3)使用下面的代码

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
    myCollectionViewHeight.constant = height
    self.view.layoutIfNeeded()
}

回答by n13

Took the solution by d4Rk which is great, except in my case it would keep cutting off the bottom of my collection view (too short). I figured out this was because intrinsic content size was sometimes 0 and this would throw off the calculations. IDK. All I know is this fixed it.

采用 d4Rk 的解决方案,这很棒,但在我的情况下,它会不断切断我的收藏视图的底部(太短)。我发现这是因为内在内容大小有时为 0,这会影响计算。身。我所知道的是这修复了它。

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))
    }

}

回答by parthiban

Do following.

做以下。

  1. first set height constrain for UICollectionView
  2. here calendarBaseViewHeightis UICollectionViewheight Variable
  3. call the function after reload the collection view

    func resizeCollectionViewSize(){  
           calendarBaseViewHeight.constant = collectionView.contentSize.height      
     }
    
  1. 首先设置高度约束 UICollectionView
  2. calendarBaseViewHeightUICollectionView高度变量
  3. 重新加载集合视图后调用该函数

    func resizeCollectionViewSize(){  
           calendarBaseViewHeight.constant = collectionView.contentSize.height      
     }
    

回答by Tyten

This seemed like the simplest solution for me.

这对我来说似乎是最简单的解决方案。

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
    }
}

You may not need to override reloadData

您可能不需要覆盖 reloadData

回答by Matloob Hasnain

first of all calculate number of cells than multiply it with height of cell and then return height in this method

首先计算单元格的数量,然后将其乘以单元格的高度,然后在此方法中返回高度

    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

回答by peyman jani

work for me

为我工作

    let heightRes = resCollectionView.collectionViewLayout.collectionViewContentSize.height
    foodHeightConstrant.constant = height.advanced(by: 1 )

    foodCollectionView.setNeedsLayout()
    foodCollectionView.layoutIfNeeded()