Swift:如何使用snapkit获得正确的UICollectionView高度?

我可能会以完全错误的方式去解决这个问题,因为我尝试做的应该很简单…我有一个包含几个子视图的视图组件,其中一个是UICollectionView。 我使用SnapKit布局子视图。 UICollectionView是button的stream程布局,跨越0到n行,button的数量从一开始就是已知的。

当我通过SnapKitconfiguration约束时,Collection的高度为0,因为没有任何项目(cellForItemAt仍然没有调用)。

我将如何去获得在SnapKit中dynamic设置集合的高度? 还是有更好的方式来获得我正在寻找的基本stream程布局(dynamicheigth-adjustement)?

(注:代码有点简单,只显示相关部分)

class CategoryList: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate { var categories : [String]? var buttons = [BorderedButton]() private(set) lazy var collectionView: UICollectionView = { var flowLayout = UICollectionViewFlowLayout() let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: flowLayout) collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell") collectionView.delegate = self collectionView.dataSource = self collectionView.backgroundColor = UIColor.cyan return collectionView }() override func loadView() { super.loadView() self.view.addSubview(collectionView) } override func viewDidLoad() { super.viewDidLoad() setupConstraints() } override func viewDidAppear(_ animated: Bool) { print("123: \(collectionView.contentSize.height)") //prints 47 for this particular example, however doing snp.makeConstraints //(or remakeConstraints) from here doesn't make any difference //setupConstraints() } func configure(categories:[String]) { self.categories = categories for category in categories { let button = BorderedButton() button.setTitle(category, for: .normal) buttons.append(button) } } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return buttons.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) cell.addSubview(buttons[indexPath.row]) //prints 47 for this particular example, however doing snp.makeConstraints //(or remakeConstraints) from here doesn't make any difference print("XYZ: \(collectionView.contentSize.height)") return cell } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return buttons[indexPath.row].intrinsicContentSize } private func setupConstraints() { collectionView.snp.makeConstraints { (make) in make.left.top.equalToSuperview() make.width.equalTo(300) print("ABC: \(collectionView.contentSize.height)") //this does not work since height=0 make.height.equalTo(collectionView.contentSize.height) //this works fine make.height.equalTo(47) } } } 

谢谢!

编辑:添加缺less的类

感谢下面的回复。 它确实有效,很好,你可以得到的问题,即使我错过了包括一半的代码:-)下面是缺less的一块,它是使用CategoryList的类。 在你的帮助下,我得到的CategoryListdynamic扩展到正确的高度,这是非常好的。 但是,它会弄乱周围视图(view1和view2)的位置。 我怀疑这跟这个有关系

make.height.equalTo(categoryList.collectionView.snp.height)

行,也许它应该只是引用collectionView约束属性,但我不知道该怎么做(甚至可以)呢?

 class PlaylistDetailsHeaderView : UITableViewCell { private var categoryList:CategoryList private(set) lazy var view1: UIView = { let view = UIView() return view }() private(set) lazy var view2: UIView = { let view = UIView() return view }() override init(style: UITableViewCellStyle, reuseIdentifier: String?) { self.categoryList = CategoryList() super.init(style: style, reuseIdentifier: reuseIdentifier) self.contentView.addSubview(view1) self.contentView.addSubview(view2) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func configure() { let categories = ["alfa", "beta", "gamma", "fkdiii", "keoooe", "dfdsje", "jkjfldsjflsd", "alfa", "beta", "gamma", "fkdiii", "keoooe", "dfdsje", "jkjfldsjflsd"] categoryList.configure(categories: categories) self.contentView.addSubview(categoryList.view) setupConstraints() } private func setupConstraints() { view1.snp.makeConstraints { make in make.left.top.equalToSuperview() } categoryList.view.snp.makeConstraints{ make in make.left.equalToSuperview() make.top.equalTo(view1.snp.bottom).offset(20) make.width.equalTo(300) make.height.equalTo(categoryList.collectionView.snp.height) } view2.snp.makeConstraints { make in make.top.equalTo(categoryList.view.snp.bottom).offset(20) } } } 

如果我明白你的意思,我认为你应该这样做。

首先你需要将高度存储在某个地方。 这将默认为0,或在你的情况47。

 var heightConstraint: Constraint? 

然后你会像正常一样在snapkit中设置约束条件,但是当你设置高度约束条件时,将它存储在先前创build的variables中。 不要忘记添加“.constraint”。

 heightConstraint = make.height.equalTo(47).constraint 

下一步是在填充collectionView时,可以再次使用heightConstraint(如果使variables可达)

 heightConstraint.updateOffset(collectionView.contentSize.height)