普通 CollectionView 单元格中的动态 CollectionView 单元格

Posted

技术标签:

【中文标题】普通 CollectionView 单元格中的动态 CollectionView 单元格【英文标题】:Dynamic CollectionView cell in a normal CollectionView cell 【发布时间】:2020-05-02 22:40:39 【问题描述】:

我在 CollectionView 单元格中使用带有 CollectionView 的情节提要。我需要里面的那个来根据数组中给出的文本调整高度并将其连接到我的 UILabel。

我发布了一个答案,请随意使用!

【问题讨论】:

你面临什么问题? 【参考方案1】:

这是一个snippet,用于测量字符串的大小。 (您可能需要将默认值 220 更改为适合您需要的值。)

extension String 
    func size(width:CGFloat = 220.0, font: UIFont = UIFont.systemFont(ofSize: 17.0, weight: .regular)) -> CGSize 
        let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
        label.numberOfLines = 0
        label.lineBreakMode = NSLineBreakMode.byWordWrapping
        label.font = font
        label.text = self

        label.sizeToFit()

        return CGSize(width: label.frame.width, height: label.frame.height)        
        

在您的 collectionViewController 中,确保您在视图控制器中继承 UICollectionViewDelegateFlowLayout

class yourViewController : UICollectionViewController, UICollectionViewDelegateFlowLayout 

然后实现sizeForItemAt函数:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    let yourString = yourStringArray[indexPath.row]
    let padding = CGSize.init(width: 20, height: 20)
    let textSize = yourString.size(width: collectionView.frame.width) // you can also specify a font with fontSize and weight. Default is set to the system font with fontSize 17.
    return CGSize.init(width: textSize.width + (padding.width / 2), height: textSize.height + (padding.height / 2))

注意:我已经为你的单元格添加了任意边距,每边有 10 个,所以你可能需要根据你希望你的单元格的样子添加填充。 'size' 仅根据其文本测量标签的大小。

【讨论】:

我试过了......它对我不起作用。 CollectionView 是 CollectionView 单元格,而 CollectionView 单元格位于包含另一个 CollectionView 的 TableView 单元格中......那么我将如何在我的 CollectionView 类中实现它? @Douglas,在这种情况下,您不应该继承 UICollectionViewController,只需将您的单元格声明为“class MyCell: UICollectionViewCell, UICollectionViewDelegateFlowLayout”。此外,请确保“大小”扩展代码未粘贴到另一个类中。我通常将扩展名放在一个名为 Extensions.swift 的文件中。 你能给我一个例子,说明我如何使用我的 IBOutlet 标签,而不是你在函数中声明为标签的标签吗?否则,当您使用情节提要时,它是如何工作的? @Douglas,扩展函数创建一个标签只是为了计算文本大小。这不会出现在您的应用程序中,因为它从未添加到视图中,并且会被 ios 自动从内存中删除。该功能不会影响您的故事板或您分配文本的实际标签。您将需要根据您的布局为单元格添加填充。使用它的一个例子是我在这个 showPopover 扩展中设置首选大小的 SwiftSnippets 故事板项目:github.com/elliott-io/SwiftSnippets/blob/master/… 什么是故事板填充的例子,因为没有任何工作......我不确定你想让我从中得到什么......你给了我一半的答案跨度> 【参考方案2】:

这正是我想要的……但任何人都可以随意将它与您的故事板 collectionView 一起使用。

您的 collectionView 所在的位置:

import UIKit

class ViewController: UIViewController 

    @IBOutlet weak var CV: UICollectionView!

     let screenSize: CGRect = UIScreen.main.bounds

    var array = ["Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Dignissim enim sit amet venenatis urna cursus eget nunc. Congue nisi vitae suscipit tellus mauris a diam maecenas sed. Ac tortor vitae purus faucibus ornare suspendisse sed nisi lacus. Arcu risus quis varius quam quisque. Sit amet consectetur adipiscing elit pellentesque. Tellus cras adipiscing enim eu. Eros in cursus turpis massa tincidunt. Non diam phasellus vestibulum lorem sed risus ultricies tristique. Enim nunc faucibus a pellentesque sit amet. Aliquet nec ullamcorper sit amet. Turpis massa tincidunt dui ut. Iaculis urna id volutpat lacus laoreet non curabitur. Congue mauris rhoncus aenean vel elit scelerisque mauris pellentesque. Commodo ullamcorper a lacus vestibulum sed arcu non odio. Quis auctor elit sed vulputate. Molestie nunc non blandit massa enim nec. Tempus imperdiet nulla malesuada pellentesque elit eget gravida cum sociis. Facilisis volutpat est velit egestas dui id ornare arcu. Sociis natoque penatibus et magnis dis parturient montes nascetur ridiculus."]

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        CV.delegate = self
        CV.dataSource = self
    


extension ViewController : UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        array.count
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = CV.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! Cell
        cell.TextPosted.text = array[indexPath.item]
        //cell.layoutIfNeeded()
        return cell
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        return CGSize(width: screenSize.width, height: 175)
    

现在是你的标签:

import UIKit

class Cell: UICollectionViewCell 

    @IBOutlet weak var TextPosted: UILabel!

        override func awakeFromNib() 
            let screenSize: CGRect = UIScreen.main.bounds
            contentView.widthAnchor.constraint(equalToConstant: screenSize.width).isActive = true
            contentView.heightAnchor.constraint(greaterThanOrEqualToConstant: 175).isActive = true

            TextPosted.numberOfLines = 0
            TextPosted.translatesAutoresizingMaskIntoConstraints = false
            TextPosted.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
            //Left Side
            TextPosted.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
            //Right Side
            TextPosted.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
            //Bottom Space between contentView and text
            TextPosted.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -10).isActive = true
    

【讨论】:

以上是关于普通 CollectionView 单元格中的动态 CollectionView 单元格的主要内容,如果未能解决你的问题,请参考以下文章

多个tableView单元格中的多个collectionView

如何快速更新消息 CollectionView 单元格中的数据?

如何将手势识别器添加到collectionview单元格中的uiview

collectionview 单元格中的阴影与 swift 中的其他单元格的行为方式不同

如何在 tvos 应用程序的 collectionview 单元格中的按钮上移动焦点?

原型单元格中带有 CollectionView 的动态 TableView