ios 如何使用 FlowLayout 确定 UICollectionView 的高度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13788522/
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
How to determine height of UICollectionView with FlowLayout
提问by Ignatius Tremor
I've got an UICollectionView
with an UICollectionViewFlowLayout
, and i want to calculate its content size (for return in intrinsicContentSize
needed for adjusting its height via AutoLayout).
我有一个UICollectionView
带UICollectionViewFlowLayout
,我想计算它的内容大小(用于intrinsicContentSize
通过 AutoLayout 调整其高度所需的返回值)。
The problems is: Even if I have a fixed and equal height for all cells, I don't know how many "rows"/lines I have in the UICollectionView
. I also can't determine that count by the number of items in my data source, since the cells representing the data items vary in width, so does consequently the number of items I have in one line of the UICollectionView
.
问题是:即使我对所有单元格都有固定且相等的高度,我也不知道UICollectionView
. 我也无法通过数据源中的项目数来确定该计数,因为表示数据项的单元格的宽度不同,因此我在UICollectionView
.
Since I couldn't find any hints on this topic in the official documentation and googling didn't bring me any further, any help and ideas would be appreciated very much.
由于我在官方文档中找不到关于这个主题的任何提示,谷歌搜索也没有给我带来任何进一步的帮助和想法,我们将不胜感激。
回答by Ignatius Tremor
Whoa! For some reason, after hours of research, I now found a pretty easy answer to my question: I was completely searching in the wrong place, digging through all the documentation I could find on UICollectionView
.
哇!出于某种原因,经过数小时的研究,我现在找到了一个非常简单的问题的答案:我完全在错误的地方搜索,挖掘了我能在UICollectionView
.
The simple and easy solution lies in the underlying layout: Just call collectionViewContentSize
on your myCollectionView.collectionViewLayout
property and you get the height and width of the content as CGSize
. It's as easy as that.
简单易行的解决方案在于底层布局:只需调用collectionViewContentSize
您的myCollectionView.collectionViewLayout
属性,即可获得内容的高度和宽度CGSize
。就这么简单。
回答by user1046037
In case you are using Auto layout, then you could create a subclass of UICollectionView
如果您使用的是Auto layout,那么您可以创建一个子类UICollectionView
If you use the below the code then you don't have to specify any height constraints for the collection view as it would vary based on the contents of the collection view.
如果您使用下面的代码,那么您不必为集合视图指定任何高度约束,因为它会根据集合视图的内容而变化。
Given below is the implementation:
下面给出的是实现:
@interface DynamicCollectionView : UICollectionView
@end
@implementation DynamicCollectionView
- (void) layoutSubviews
{
[super layoutSubviews];
if (!CGSizeEqualToSize(self.bounds.size, [self intrinsicContentSize]))
{
[self invalidateIntrinsicContentSize];
}
}
- (CGSize)intrinsicContentSize
{
CGSize intrinsicContentSize = self.contentSize;
return intrinsicContentSize;
}
@end
回答by lee
At viewDidAppear
you can get it by:
在viewDidAppear
你可以得到它:
float height = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;
Maybe when you reload data then need to calculate a new height with new data then you can get it by:
add observer to listen when your CollectionView
finished reload data at viewdidload
:
也许当您重新加载数据时然后需要使用新数据计算新高度然后您可以通过以下方式获得它:添加观察者以在您CollectionView
完成重新加载数据时监听viewdidload
:
[self.myCollectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL];
Then add bellow function to get new height or do anything after collectionview finished reload:
然后添加波纹管功能以获取新高度或在 collectionview 完成重新加载后执行任何操作:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
//Whatever you do here when the reloadData finished
float newHeight = self.myCollectionView.collectionViewLayout.collectionViewContentSize.height;
}
And don't forget to remove observer:
并且不要忘记删除观察者:
[self.myCollectionView removeObserver:self forKeyPath:@"contentSize" context:NULL];
回答by Nick Wood
user1046037 answer in Swift...
user1046037 在 Swift 中回答...
class DynamicCollectionView: UICollectionView {
override func layoutSubviews() {
super.layoutSubviews()
if bounds.size != intrinsicContentSize() {
invalidateIntrinsicContentSize()
}
}
override func intrinsicContentSize() -> CGSize {
return self.contentSize
}
}
回答by Mohammad Sadiq Shaikh
Swift 3 code for user1046037 answer
用户 1046037 答案的 Swift 3 代码
import UIKit
class DynamicCollectionView: UICollectionView {
override func layoutSubviews() {
super.layoutSubviews()
if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return contentSize
}
}
回答by Wilson
Swift 4
斯威夫特 4
class DynamicCollectionView: UICollectionView {
override func layoutSubviews() {
super.layoutSubviews()
if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return collectionViewLayout.collectionViewContentSize
}
}
回答by Cesare
Swift 4.2
斯威夫特 4.2
class DynamicCollectionView: UICollectionView {
override func layoutSubviews() {
super.layoutSubviews()
if bounds.size != intrinsicContentSize {
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return self.contentSize
}
}
回答by Er. Vihar
It's too late to answer this question but I have recently gone through this issue.
@lee's above answerhelp me a lot to get my answer. But that answer is limited to objective-cand I was working in swift.
@lee With reference to your answer, allow me to let the swift user get this issue solved easily. For that, please follow below steps:
现在回答这个问题为时已晚,但我最近经历了这个问题。
@lee 的上述答案对我得到答案有很大帮助。但该答案仅限于Objective-c并且我在swift中工作。
@lee 参考您的回答,请允许我让 swift 用户轻松解决此问题。为此,请按照以下步骤操作:
Declare a CGFloat
variable in declaration section:
CGFloat
在声明部分声明一个变量:
var height : CGFloat!
At viewDidAppear
you can get it by:
在viewDidAppear
你可以得到它:
height = self.myCollectionView.collectionViewLayout.collectionViewContentSize().height
Maybe when you reload
data then need to calculate a new height with new data then you can get it by: addObserver
to listen when your CollectionView
finished reload data at viewWillAppear
:
也许当您的reload
数据然后需要使用新数据计算新高度时,您可以通过以下方式获取它:addObserver
在CollectionView
完成重新加载数据时监听viewWillAppear
:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
....
....
self.shapeCollectionView.addObserver(self, forKeyPath: "contentSize", options: NSKeyValueObservingOptions.Old, context: nil)
}
Then add bellow function to get new height or do anything after collectionview
finished reload:
然后添加波纹管功能以获取新高度或在collectionview
完成重新加载后执行任何操作:
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
let newHeight : CGFloat = self.myCollectionView.collectionViewLayout.collectionViewContentSize().height
var frame : CGRect! = self.myCollectionView.frame
frame.size.height = newHeight
self.myCollectionView.frame = frame
}
And don't forget to remove observer:
并且不要忘记删除观察者:
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(true)
....
....
self.myCollectionView.removeObserver(self, forKeyPath: "contentSize")
}
I hope this will help you to solve your issue in swift.
我希望这将帮助您快速解决您的问题。
回答by HUNG TRAN DUY
This answer is based on @Er. Vihar's answer. You can easily implement the solution by using RxSwift
这个答案基于@Er。维哈尔的回答。您可以使用 RxSwift 轻松实现解决方案
collectionView.rx.observe(CGSize.self , "contentSize").subscribe(onNext: { (size) in
print("sizer \(size)")
}).disposed(by: rx.disposeBag)
回答by Pramodya Abeysinghe
assuming your collectionView is named as collectionViewyou can take the height as follows.
假设您的 collectionView 被命名为collectionView您可以按如下方式获取高度。
let height = collectionView.collectionViewLayout.collectionViewContentSize.height