简体   繁体   中英

Dynamic CollectionView cell in a normal CollectionView cell

I'm using the storyboard with a CollectionView inside a CollectionView cell. I need the one inside to resize the height based on the text given in an array and connect that to my UILabel.

I posted an answer, feel free to use it!

Here is a snippet that measures the size of a string. (You will likely need to change the default of 220 to something that suits your needs.)

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)        
    }    
}

In your collectionViewController, make sure you inherit UICollectionViewDelegateFlowLayout in your view controller:

class yourViewController : UICollectionViewController, UICollectionViewDelegateFlowLayout 

Then implement the sizeForItemAt function:

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))
}

Note: I've added arbitrary padding to your cell of 10 on all sides, so you likely will need to add padding based on what you want your cell to look like. 'size' only measures a label's size based on its text.

This is simply what I was looking for... but anyone feel free to use it with your storyboard collectionView.

Where your collectionView is at:

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)
    }
}

And now your Label:

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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM