Vertical UICollectionView with different item size

无人久伴 提交于 2020-07-22 10:58:49

问题


I want to create a UICollectionView that has different item size. It is similar to this image.

It is a Vertical UICollectionView.


    class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical

        let collectionView = CollectionView(frame: .zero, collectionViewLayout: layout)
        view.addSubview(collectionView)
        collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        collectionView.heightAnchor.constraint(equalToConstant: 240).isActive = true
        collectionView.translatesAutoresizingMaskIntoConstraints = false
    }
}


class CollectionView: UICollectionView {
    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
        super.init(frame: frame, collectionViewLayout: layout)
        self.register(CollectionViewCell.self, forCellWithReuseIdentifier: CollectionViewCell.identifier)
        self.dataSource = self
        self.delegate = self
        self.isPagingEnabled = true

    }

    required init?(coder: NSCoder) {
        fatalError()
    }

}

extension CollectionView: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CollectionViewCell.identifier, for: indexPath) as! CollectionViewCell
        cell.backgroundColor = .blue
        cell.label.text = "\(indexPath.row)"

        let row = indexPath.row
        switch row {
        case 0:
            cell.backgroundColor = .red
        case 1:
            cell.backgroundColor = .blue
        case 2:
            cell.backgroundColor = .purple
        case 3:
            cell.backgroundColor = .orange
        case 4:
            cell.backgroundColor = .cyan
        case 5:
            cell.backgroundColor = .green
        case 6:
            cell.backgroundColor = .magenta
        default:
            cell.backgroundColor = .systemPink
        }
        return cell
    }


}

extension  CollectionView: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let row = indexPath.row
        let width = collectionView.frame.width
        let other = width / 3

        let height = collectionView.frame.height
        let o_height =  height / 3
        switch row {
        case 0:
            return CGSize(width: other * 2, height: o_height * 2)
        case 1, 2, 5:
            return CGSize(width: other, height: o_height)
        case 3:
            return CGSize(width: other, height: o_height)
        case 4:
            return CGSize(width: other, height: o_height)
        default:
            return CGSize(width: width, height: height)
        }
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return .leastNormalMagnitude
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return .leastNormalMagnitude
    }
}



class CollectionViewCell: UICollectionViewCell {
    static let identifier = "CollectionViewCell"

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.contentView.addSubview(label)
        label.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        label.translatesAutoresizingMaskIntoConstraints = false
    }

    required init?(coder: NSCoder) {
        fatalError()
    }
}

I have used the above code. It does not work: the second item is not in the correct position: there are empty space before and afte of it. As a result, the rest of the items are pushed down.

Thanks in advance!


Update

It works if I use horizontal scroll and change width of item 1.

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let row = indexPath.row
    let width = collectionView.frame.width
    let other = width / 3

    let height = collectionView.frame.height
    let o_height =  height / 3
    switch row {
    case 0:
        return CGSize(width: other * 2, height: o_height * 2)
    case 1:
            return CGSize(width: other * 2, height: o_height)
    case 2:
        return CGSize(width: other, height: o_height)
    case 3:
        return CGSize(width: other, height: o_height)
    case 4:
        return CGSize(width: other, height: o_height)
    default:
        return CGSize(width: width, height: height)
    }
} 

来源:https://stackoverflow.com/questions/62302585/vertical-uicollectionview-with-different-item-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!