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

Posted

技术标签:

【中文标题】如何根据 UITableViewCell 中的内容调整水平 UICollectionView 的高度【英文标题】:How to resize a horizontal UICollectionView height based on its content in a UITableViewCell 【发布时间】:2018-10-24 13:10:25 【问题描述】:

我正在尝试将UICollectionView 放在UITableViewCell 中。我想通过分页在UICollectionViewCells 中显示 cmets。 cmets 中可能有不止一行,所以如果注释标签中的行超过一行,我想调整 UICollectionView 的大小。

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

单元格将如下所示。

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

【问题讨论】:

【参考方案1】:

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

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

`@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 上还有一个工作演示

【讨论】:

您好,谢谢您的回答。我尝试使用您的答案将UICollectionView 放在UITableViewCell 中。已经好几个小时了,无法完成。你能修复我在问题中链接的演示吗?【参考方案2】:

对于基于内容长度的动态单元格大小,您基本上必须做一些近似。所以这是我的解决方案。它涉及到几次反复试验才能使计算正确。现在请耐心等待!

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 是​​它们之间的差距或边距。只要你给它最小值,它就可以工作。如果你给它一个太高的值,它并不会真正影响结果。所以实验吧!

【讨论】:

抱歉,我没看懂datasource?.item(indexPath) as? User 部分。我应该在哪里覆盖这个方法? 我正在使用一个框架。您只需要引用您要显示的元素。在 MainViewControler 中覆盖此方法。我已经用更多解释更新了解决方案。请查看更新。 UICollectionViewUITableViewCell 中,我还应该将它放在 MainViewController 中吗? Xcode 说Method does not override any method from its superclass 您是使用 StoryBoard 还是 Pure Code 构建它? 带故事板

以上是关于如何根据 UITableViewCell 中的内容调整水平 UICollectionView 的高度的主要内容,如果未能解决你的问题,请参考以下文章

动态 UITableViewCell 不根据内容调整大小

如何从 cgpoint 获取 UItableviewcell?

UITableViewCell 高度根据行内容使用自动布局动态计算

带有 UIWebview 的 UITableViewCell,可根据内容大小调整高度

根据内容可用性调整 UITableViewCell 的大小作为响应

根据 UITableViewCell 中 UIImageView 中的图像设置 UIView 宽度