如何根据UITableViewCell中的内容调整水平UICollectionView的高度

时间:2018-10-24 13:10:25

标签: ios swift uitableview uicollectionview uicollectionviewcell

我正在尝试将UICollectionView放在UITableViewCell中。我想在UICollectionViewCell s中分页显示评论。注释中可能有多行,因此如果注释标签中有多行,我想调整UICollectionView的大小。

This is the demo project for the question.,如果您能解决此演示中的问题,我将不胜感激。

这些单元格看起来像这样。

enter image description here

我尝试了一些答案,但没有取得任何进展。你能告诉我我需要逐步做些什么吗?如果可以共享,演示会更好。谢谢。

2 个答案:

答案 0 :(得分:2)

好..所以我遇到了同样的问题...我通过以下步骤对其进行了修复...

创建一个集合视图的高度约束出口,您将根据您拥有的动态内容进行设置。

`@IBOutlet private(set) weak var collectionViewHeightConstraint: NSLayoutConstraint!`

找到最大的内容模型(在您的情况下,这将是最大的注释),并找到最大的集合视图单元格的高度。可以通过以下方法完成。

private func getSizingCellHeight(for item: T.YourModel) -> CGFloat {
    guard let sizingCell = sizingCell else {
        return 0
    }

    sizingCell.frame.size.width = collectionViewItemWidth // This would be the width your collection view has
    sizingCell.prepareForReuse()

    // This is the method inside of your collection view cell, which lays out the content of the cell 
    sizingCell.configure(with: item)
    sizingCell.layoutIfNeeded()

    var fittingSize = UILayoutFittingCompressedSize
    fittingSize.width = collectionViewItemWidth

    let size = sizingCell.contentView.systemLayoutSizeFitting(
        fittingSize,
        withHorizontalFittingPriority: .required,
        verticalFittingPriority: .defaultLow
    )

    return size.height
}

运行上述方法将为您提供最大单元格的高度,您可以将其用于collectionView的高度约束。

private func setCollectionViewHeight() {
    var largestHeight: CGFloat = 0

    //items would be your datasource for the collection view
    let items: [YourModel] = .... with some values
    if let items = items {
        for item in items {
            let height = getSizingCellHeight(for: item)
            if height > largestHeight {
                largestHeight = height
            }
        }
    }

    collectionViewHeightConstraint?.constant = largestHeight
}

这是我在项目中拥有的实际工作代码。

根据我上一次记得的内容,我遵循了Charlie's Article

该文章还针对Github

进行了演示

答案 1 :(得分:-1)

对于基于内容长度的动态单元格大小调整,您基本上必须进行一些近似。所以这是我的解决方案。要进行正确的计算,需要反复试验。请现在忍受我!

override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    if let user = datasource?.item(indexPath) as? User {
        let approximateWidthBioTextView = view.frame.width - 10 - 60 - 10
        let size = CGSize(width: approximateWidthBioTextView, height: 1000)
        let attributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 15)]

        let estimatedFrame = NSString(string: user.bio).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)

        return CGSize(width: view.frame.width, height: estimatedFrame.height + 73)
    }

    return CGSize(width: view.frame.width, height: 200)
}

基本上,您需要更改sizeForItem函数并进行一些近似。我的内容由User Class的实例确定。因此,请确保在开始引用单元格中包含的内容之前,先进行确认。在我的情况下,需要显示用户。简而言之,我的解决方案就是基于user.bioText的单元格高度。因为这是唯一改变单元格大小的元素。因此,请记住这一点。

首先,您必须使用它来计算collectionView。在我的情况下,它是框架的宽度减去边距(10、60和10)。请记住,做到这一点很重要。

第二,为了估计单元格的高度,我们需要将其包装在一个具有一些需要填写的属性的矩形中。在size常量中,我们故意给出一个高值,以便系统获取实际需要的值。现在,对于属性(如果您的内容是我的情况下的字符串),请确保您使用相同的字体大小。

最后,在返回部分return CGSize(width: view.frame.width, height: estimatedFrame.height + 73)中,我们仍然必须进行一些更正,因为如果我可以说的话,文本具有一些内部填充,并且除非您对此进行纠正,否则您的单元格将无法正确显示。确保使用最后一个值estimatedFrame.height + 73(在我的情况下为73),直到达到动态地完美分配单元格的地步。那是唯一的方法。它肯定对我有用。

顺便说一句,如果您的代码看起来有点不同(也不太相似),请不要打扰。我使用的是框架,但计算原理相同。如果您问自己,73值从何而来,那是因为在我需要在每个单元格中显示的生物文本的顶部,我的用户名和用户名标签都由20的8组成,所以40两者之间的差距为33。只要您给它最小值,它就应该起作用。如果给它一个太高的值,它并不会真正影响结果。试试吧!