create a ui collection view with ten items that dynamically changes in size in swift

To create a UICollectionView that dynamically changes its size based on its contents, you will need to implement the UICollectionViewDelegateFlowLayout protocol in your UIViewController or UICollectionView subclass.

Here is a sample code that will display 10 cells in a grid, with each cell's size determined dynamically based on its content.

main.swift
import UIKit

class MyViewController: UIViewController {

    let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        return UICollectionView(frame: .zero, collectionViewLayout: layout)
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.register(MyCell.self, forCellWithReuseIdentifier: "MyCell")
        collectionView.dataSource = self
        collectionView.delegate = self

        collectionView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(collectionView)

        NSLayoutConstraint.activate([
            collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            collectionView.topAnchor.constraint(equalTo: view.topAnchor),
            collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])
    }
}

extension MyViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath) as! MyCell
        cell.label.text = "Cell \(indexPath.item)"
        return cell
    }
}

extension MyViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let cellWidth: CGFloat = collectionView.bounds.width / 2
        let cellHeight: CGFloat = 100 // You can calculate this based on your content
        return CGSize(width: cellWidth, height: cellHeight)
    }
}

class MyCell: UICollectionViewCell {
    
    let label = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        label.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(label)
        
        NSLayoutConstraint.activate([
            label.topAnchor.constraint(equalTo: contentView.topAnchor),
            label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
            label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
2694 chars
72 lines

In this example, we first create an instance of UICollectionViewFlowLayout, then create a UICollectionView instance with that layout. We then register a custom cell class called MyCell. We then configure the UICollectionView using Autolayout and set the data source and delegate to the view controller.

In numberOfItemsInSection, we return 10, which is the number of cells we want to display. In cellForItemAt, we dequeue a cell from the reuse pool, configure it with the appropriate data, and return it to be displayed on the screen.

In collectionView(_:layout:sizeForItemAt:), we calculate the size of each cell based on the width of the UICollectionView and the height required to display the contents of the cell. In this example, we have set the height of each cell to be 100 points.

Finally, we define a custom cell class called MyCell that displays a single label. We use Autolayout to add the label to the view hierarchy and pin it to the edges of the cell's contentView.

gistlibby LogSnag