使用 UICollectionViewCompositionalLayout 自动调整单元格大小

时间:2021-04-01 14:55:08

标签: uicollectionview uicollectionviewcompositionallayout

下面生成高度等于 estimatedHeight 的行。它不会根据 UILabel title 的高度自动调整单元格大小。 .estimated 的作用类似于 .absolute,这不是预期的。

class ViewController: UIViewController {
    var myCollectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        myCollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: createLayout())
        myCollectionView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(myCollectionView)

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

        myCollectionView.register(AdvanceFeedCell.self, forCellWithReuseIdentifier: "AdvanceFeedCell")
        myCollectionView.dataSource = self
        
        myCollectionView.delegate = self

    }

    private func createLayout() -> UICollectionViewLayout {
        let estimatedHeight: CGFloat = 450
        let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                              heightDimension: .estimated(estimatedHeight))
        let item = NSCollectionLayoutItem(layoutSize: itemSize)

        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                               heightDimension: .estimated(estimatedHeight))
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize,
                                                       subitems: [item])
        let section = NSCollectionLayoutSection(group: group)

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }

}

extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 200
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AdvanceFeedCell", for: indexPath) as! AdvanceFeedCell

        let fontDesc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .body)
        let font = UIFont.init(name: "ArialRoundedMTBold", size: fontDesc.pointSize)
        cell.title.attributedText = NSAttributedString(string: self.randomString(length: 100), attributes: [NSAttributedString.Key.font: font as Any])


        cell.layoutIfNeeded()
        return cell
    }

    func randomString(length: Int) -> String {

        let letters: NSString = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        let len = UInt32(letters.length)

        var randomString = ""

        for _ in 0 ..< length {
            let rand = arc4random_uniform(len)
            var nextChar = letters.character(at: Int(rand))
            randomString += NSString(characters: &nextChar, length: 1) as String
        }

        return randomString
    }
}

class AdvanceFeedCell: UICollectionViewCell {

    fileprivate func setupViews() {
        contentView.addSubview(title)
        NSLayoutConstraint.activate([
            title.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 0),
            title.leftAnchor.constraint(equalTo: contentView.leftAnchor, constant: 0),
            title.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: 0),
            title.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: 0),
        ])
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.backgroundColor = UIColor.gray
        setupViews()
    }

    let title: UILabel = {
        let label = UILabel()
        label.numberOfLines = 2
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

0 个答案:

没有答案