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

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

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

单元格将如下所示。

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

【问题讨论】:

    标签: ios swift uitableview uicollectionview uicollectionviewcell


    【解决方案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 构建它?
    • 带故事板
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多